Merge branch 'master' of https://github.com/Prusa-Development/PrusaSlicerPrivate into et_show_sla_supports

This commit is contained in:
enricoturri1966 2023-03-24 08:49:35 +01:00
commit 98346824e8
104 changed files with 1291 additions and 1159 deletions

View File

@ -87,6 +87,7 @@ src/slic3r/GUI/UpdateDialogs.cpp
src/slic3r/GUI/WipeTowerDialog.cpp src/slic3r/GUI/WipeTowerDialog.cpp
src/slic3r/GUI/wxExtensions.cpp src/slic3r/GUI/wxExtensions.cpp
src/slic3r/Utils/AstroBox.cpp src/slic3r/Utils/AstroBox.cpp
src/slic3r/Utils/AppUpdater.cpp
src/slic3r/Utils/Duet.cpp src/slic3r/Utils/Duet.cpp
src/slic3r/Utils/FixModelByWin10.cpp src/slic3r/Utils/FixModelByWin10.cpp
src/slic3r/Utils/FlashAir.cpp src/slic3r/Utils/FlashAir.cpp
@ -101,6 +102,7 @@ src/libslic3r/ExtrusionEntity.cpp
src/libslic3r/Flow.cpp src/libslic3r/Flow.cpp
src/libslic3r/Format/3mf.cpp src/libslic3r/Format/3mf.cpp
src/libslic3r/Format/AMF.cpp src/libslic3r/Format/AMF.cpp
src/libslic3r/Format/SLAArchiveReader.cpp
src/libslic3r/GCode/PostProcessor.cpp src/libslic3r/GCode/PostProcessor.cpp
src/libslic3r/miniz_extension.cpp src/libslic3r/miniz_extension.cpp
src/libslic3r/Preset.cpp src/libslic3r/Preset.cpp
@ -113,3 +115,4 @@ src/libslic3r/PrintBase.cpp
src/libslic3r/PrintConfig.cpp src/libslic3r/PrintConfig.cpp
src/libslic3r/Zipper.cpp src/libslic3r/Zipper.cpp
src/libslic3r/PrintObject.cpp src/libslic3r/PrintObject.cpp
src/libslic3r/PrintObjectSlice.cpp

View File

@ -340,12 +340,6 @@ std::string AppConfig::load(const std::string &path)
// Error while parsing config file. We'll customize the error message and rethrow to be displayed. // Error while parsing config file. We'll customize the error message and rethrow to be displayed.
// ! But to avoid the use of _utf8 (related to use of wxWidgets) // ! But to avoid the use of _utf8 (related to use of wxWidgets)
// we will rethrow this exception from the place of load() call, if returned value wouldn't be empty // we will rethrow this exception from the place of load() call, if returned value wouldn't be empty
/*
throw Slic3r::RuntimeError(
_utf8(L("Error parsing PrusaSlicer config file, it is probably corrupted. "
"Try to manually delete the file to recover from the error. Your user profiles will not be affected.")) +
"\n\n" + AppConfig::config_path() + "\n\n" + ex.what());
*/
return ex.what(); return ex.what();
} }
} }

View File

@ -4,7 +4,6 @@
#include <string_view> #include <string_view>
#include <cassert> #include <cassert>
#define L(s) (s)
namespace Slic3r { namespace Slic3r {

View File

@ -6,9 +6,6 @@
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
// Mark string for localization and translate.
#define L(s) Slic3r::I18N::translate(s)
namespace Slic3r { namespace Slic3r {
FlowErrorNegativeSpacing::FlowErrorNegativeSpacing() : FlowErrorNegativeSpacing::FlowErrorNegativeSpacing() :
@ -58,7 +55,7 @@ static inline FlowRole opt_key_to_flow_role(const std::string &opt_key)
static inline void throw_on_missing_variable(const std::string &opt_key, const char *dependent_opt_key) static inline void throw_on_missing_variable(const std::string &opt_key, const char *dependent_opt_key)
{ {
throw FlowErrorMissingVariable((boost::format(L("Cannot calculate extrusion width for %1%: Variable \"%2%\" not accessible.")) % opt_key % dependent_opt_key).str()); throw FlowErrorMissingVariable((boost::format(_u8L("Cannot calculate extrusion width for %1%: Variable \"%2%\" not accessible.")) % opt_key % dependent_opt_key).str());
} }
// Used to provide hints to the user on default extrusion width values, and to provide reasonable values to the PlaceholderParser. // Used to provide hints to the user on default extrusion width values, and to provide reasonable values to the PlaceholderParser.

View File

@ -296,11 +296,6 @@ bool is_valid_object_type(const std::string& type)
namespace Slic3r { namespace Slic3r {
//! macro used to mark string used at localization,
//! return same string
#define L(s) (s)
#define _(s) Slic3r::I18N::translate(s)
// Base class with error messages management // Base class with error messages management
class _3MF_Base class _3MF_Base
{ {
@ -1875,9 +1870,9 @@ namespace Slic3r {
if (m_curr_metadata_name == SLIC3RPE_3MF_VERSION) { if (m_curr_metadata_name == SLIC3RPE_3MF_VERSION) {
m_version = (unsigned int)atoi(m_curr_characters.c_str()); m_version = (unsigned int)atoi(m_curr_characters.c_str());
if (m_check_version && (m_version > VERSION_3MF_COMPATIBLE)) { if (m_check_version && (m_version > VERSION_3MF_COMPATIBLE)) {
// std::string msg = _(L("The selected 3mf file has been saved with a newer version of " + std::string(SLIC3R_APP_NAME) + " and is not compatible.")); // std::string msg = _u8L("The selected 3mf file has been saved with a newer version of " + std::string(SLIC3R_APP_NAME) + " and is not compatible.");
// throw version_error(msg.c_str()); // throw version_error(msg.c_str());
const std::string msg = (boost::format(_(L("The selected 3mf file has been saved with a newer version of %1% and is not compatible."))) % std::string(SLIC3R_APP_NAME)).str(); const std::string msg = (boost::format(_u8L("The selected 3mf file has been saved with a newer version of %1% and is not compatible.")) % std::string(SLIC3R_APP_NAME)).str();
throw version_error(msg); throw version_error(msg);
} }
} else if (m_curr_metadata_name == "Application") { } else if (m_curr_metadata_name == "Application") {
@ -1888,15 +1883,15 @@ namespace Slic3r {
} else if (m_curr_metadata_name == SLIC3RPE_FDM_SUPPORTS_PAINTING_VERSION) { } else if (m_curr_metadata_name == SLIC3RPE_FDM_SUPPORTS_PAINTING_VERSION) {
m_fdm_supports_painting_version = (unsigned int) atoi(m_curr_characters.c_str()); m_fdm_supports_painting_version = (unsigned int) atoi(m_curr_characters.c_str());
check_painting_version(m_fdm_supports_painting_version, FDM_SUPPORTS_PAINTING_VERSION, check_painting_version(m_fdm_supports_painting_version, FDM_SUPPORTS_PAINTING_VERSION,
_(L("The selected 3MF contains FDM supports painted object using a newer version of PrusaSlicer and is not compatible."))); _u8L("The selected 3MF contains FDM supports painted object using a newer version of PrusaSlicer and is not compatible."));
} else if (m_curr_metadata_name == SLIC3RPE_SEAM_PAINTING_VERSION) { } else if (m_curr_metadata_name == SLIC3RPE_SEAM_PAINTING_VERSION) {
m_seam_painting_version = (unsigned int) atoi(m_curr_characters.c_str()); m_seam_painting_version = (unsigned int) atoi(m_curr_characters.c_str());
check_painting_version(m_seam_painting_version, SEAM_PAINTING_VERSION, check_painting_version(m_seam_painting_version, SEAM_PAINTING_VERSION,
_(L("The selected 3MF contains seam painted object using a newer version of PrusaSlicer and is not compatible."))); _u8L("The selected 3MF contains seam painted object using a newer version of PrusaSlicer and is not compatible."));
} else if (m_curr_metadata_name == SLIC3RPE_MM_PAINTING_VERSION) { } else if (m_curr_metadata_name == SLIC3RPE_MM_PAINTING_VERSION) {
m_mm_painting_version = (unsigned int) atoi(m_curr_characters.c_str()); m_mm_painting_version = (unsigned int) atoi(m_curr_characters.c_str());
check_painting_version(m_mm_painting_version, MM_PAINTING_VERSION, check_painting_version(m_mm_painting_version, MM_PAINTING_VERSION,
_(L("The selected 3MF contains multi-material painted object using a newer version of PrusaSlicer and is not compatible."))); _u8L("The selected 3MF contains multi-material painted object using a newer version of PrusaSlicer and is not compatible."));
} }
return true; return true;

View File

@ -57,10 +57,6 @@ const char* SLIC3R_CONFIG_TYPE = "slic3rpe_config";
namespace Slic3r namespace Slic3r
{ {
//! macro used to mark string used at localization,
//! return same string
#define L(s) (s)
#define _(s) Slic3r::I18N::translate(s)
struct AMFParserContext struct AMFParserContext
{ {
@ -997,7 +993,7 @@ bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_fi
{ {
// std::string msg = _(L("The selected amf file has been saved with a newer version of " + std::string(SLIC3R_APP_NAME) + " and is not compatible.")); // std::string msg = _(L("The selected amf file has been saved with a newer version of " + std::string(SLIC3R_APP_NAME) + " and is not compatible."));
// throw Slic3r::FileIOError(msg.c_str()); // throw Slic3r::FileIOError(msg.c_str());
const std::string msg = (boost::format(_(L("The selected amf file has been saved with a newer version of %1% and is not compatible."))) % std::string(SLIC3R_APP_NAME)).str(); const std::string msg = (boost::format(_u8L("The selected amf file has been saved with a newer version of %1% and is not compatible.")) % std::string(SLIC3R_APP_NAME)).str();
throw Slic3r::FileIOError(msg); throw Slic3r::FileIOError(msg);
} }

View File

@ -7,7 +7,6 @@
#include <boost/filesystem/path.hpp> #include <boost/filesystem/path.hpp>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
constexpr const char * L(const char * str) { return str; }
#include <array> #include <array>
#include <map> #include <map>

View File

@ -71,11 +71,6 @@ using namespace std::literals::string_view_literals;
namespace Slic3r { namespace Slic3r {
//! macro used to mark string used at localization,
//! return same string
#define L(s) (s)
#define _(s) Slic3r::I18N::translate(s)
// Only add a newline in case the current G-code does not end with a newline. // Only add a newline in case the current G-code does not end with a newline.
static inline void check_add_eol(std::string& gcode) static inline void check_add_eol(std::string& gcode)
{ {
@ -487,8 +482,8 @@ GCode::ObjectsLayerToPrint GCode::collect_layers_to_print(const PrintObject& obj
// first layer may result in skirt/brim in the air and maybe other issues. // first layer may result in skirt/brim in the air and maybe other issues.
if (layers_to_print.size() == 1u) { if (layers_to_print.size() == 1u) {
if (!has_extrusions) if (!has_extrusions)
throw Slic3r::SlicingError(_(L("There is an object with no extrusions in the first layer.")) + "\n" + throw Slic3r::SlicingError(_u8L("There is an object with no extrusions in the first layer.") + "\n" +
_(L("Object name")) + ": " + object.model_object()->name); _u8L("Object name") + ": " + object.model_object()->name);
} }
// In case there are extrusions on this layer, check there is a layer to lay it on. // In case there are extrusions on this layer, check there is a layer to lay it on.
@ -518,14 +513,14 @@ GCode::ObjectsLayerToPrint GCode::collect_layers_to_print(const PrintObject& obj
std::string warning; std::string warning;
size_t i = 0; size_t i = 0;
for (i = 0; i < std::min(warning_ranges.size(), size_t(3)); ++i) for (i = 0; i < std::min(warning_ranges.size(), size_t(3)); ++i)
warning += Slic3r::format(_(L("Empty layer between %1% and %2%.")), warning += Slic3r::format(_u8L("Empty layer between %1% and %2%."),
warning_ranges[i].first, warning_ranges[i].second) + "\n"; warning_ranges[i].first, warning_ranges[i].second) + "\n";
if (i < warning_ranges.size()) if (i < warning_ranges.size())
warning += _(L("(Some lines not shown)")) + "\n"; warning += _u8L("(Some lines not shown)") + "\n";
warning += "\n"; warning += "\n";
warning += Slic3r::format(_(L("Object name: %1%")), object.model_object()->name) + "\n\n" warning += Slic3r::format(_u8L("Object name: %1%"), object.model_object()->name) + "\n\n"
+ _(L("Make sure the object is printable. This is usually caused by negligibly small extrusions or by a faulty model. " + _u8L("Make sure the object is printable. This is usually caused by negligibly small extrusions or by a faulty model. "
"Try to repair the model or change its orientation on the bed.")); "Try to repair the model or change its orientation on the bed.");
const_cast<Print*>(object.print())->active_step_add_warning( const_cast<Print*>(object.print())->active_step_add_warning(
PrintStateBase::WarningLevel::CRITICAL, warning); PrintStateBase::WarningLevel::CRITICAL, warning);
@ -655,25 +650,25 @@ namespace DoExport {
}; };
const GCodeConfig& config = print.config(); const GCodeConfig& config = print.config();
check(_(L("Start G-code")), config.start_gcode.value); check(_u8L("Start G-code"), config.start_gcode.value);
if (ret.size() < MAX_TAGS_COUNT) check(_(L("End G-code")), config.end_gcode.value); if (ret.size() < MAX_TAGS_COUNT) check(_u8L("End G-code"), config.end_gcode.value);
if (ret.size() < MAX_TAGS_COUNT) check(_(L("Before layer change G-code")), config.before_layer_gcode.value); if (ret.size() < MAX_TAGS_COUNT) check(_u8L("Before layer change G-code"), config.before_layer_gcode.value);
if (ret.size() < MAX_TAGS_COUNT) check(_(L("After layer change G-code")), config.layer_gcode.value); if (ret.size() < MAX_TAGS_COUNT) check(_u8L("After layer change G-code"), config.layer_gcode.value);
if (ret.size() < MAX_TAGS_COUNT) check(_(L("Tool change G-code")), config.toolchange_gcode.value); if (ret.size() < MAX_TAGS_COUNT) check(_u8L("Tool change G-code"), config.toolchange_gcode.value);
if (ret.size() < MAX_TAGS_COUNT) check(_(L("Between objects G-code (for sequential printing)")), config.between_objects_gcode.value); if (ret.size() < MAX_TAGS_COUNT) check(_u8L("Between objects G-code (for sequential printing)"), config.between_objects_gcode.value);
if (ret.size() < MAX_TAGS_COUNT) check(_(L("Color Change G-code")), config.color_change_gcode.value); if (ret.size() < MAX_TAGS_COUNT) check(_u8L("Color Change G-code"), config.color_change_gcode.value);
if (ret.size() < MAX_TAGS_COUNT) check(_(L("Pause Print G-code")), config.pause_print_gcode.value); if (ret.size() < MAX_TAGS_COUNT) check(_u8L("Pause Print G-code"), config.pause_print_gcode.value);
if (ret.size() < MAX_TAGS_COUNT) check(_(L("Template Custom G-code")), config.template_custom_gcode.value); if (ret.size() < MAX_TAGS_COUNT) check(_u8L("Template Custom G-code"), config.template_custom_gcode.value);
if (ret.size() < MAX_TAGS_COUNT) { if (ret.size() < MAX_TAGS_COUNT) {
for (const std::string& value : config.start_filament_gcode.values) { for (const std::string& value : config.start_filament_gcode.values) {
check(_(L("Filament Start G-code")), value); check(_u8L("Filament Start G-code"), value);
if (ret.size() == MAX_TAGS_COUNT) if (ret.size() == MAX_TAGS_COUNT)
break; break;
} }
} }
if (ret.size() < MAX_TAGS_COUNT) { if (ret.size() < MAX_TAGS_COUNT) {
for (const std::string& value : config.end_filament_gcode.values) { for (const std::string& value : config.end_filament_gcode.values) {
check(_(L("Filament End G-code")), value); check(_u8L("Filament End G-code"), value);
if (ret.size() == MAX_TAGS_COUNT) if (ret.size() == MAX_TAGS_COUNT)
break; break;
} }
@ -681,7 +676,7 @@ namespace DoExport {
if (ret.size() < MAX_TAGS_COUNT) { if (ret.size() < MAX_TAGS_COUNT) {
const CustomGCode::Info& custom_gcode_per_print_z = print.model().custom_gcode_per_print_z; const CustomGCode::Info& custom_gcode_per_print_z = print.model().custom_gcode_per_print_z;
for (const auto& gcode : custom_gcode_per_print_z.gcodes) { for (const auto& gcode : custom_gcode_per_print_z.gcodes) {
check(_(L("Custom G-code")), gcode.extra); check(_u8L("Custom G-code"), gcode.extra);
if (ret.size() == MAX_TAGS_COUNT) if (ret.size() == MAX_TAGS_COUNT)
break; break;
} }
@ -714,9 +709,9 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu
reports += source + ": \"" + keyword + "\"\n"; reports += source + ": \"" + keyword + "\"\n";
} }
print->active_step_add_warning(PrintStateBase::WarningLevel::NON_CRITICAL, print->active_step_add_warning(PrintStateBase::WarningLevel::NON_CRITICAL,
_(L("In the custom G-code were found reserved keywords:")) + "\n" + _u8L("In the custom G-code were found reserved keywords:") + "\n" +
reports + reports +
_(L("This may cause problems in g-code visualization and printing time estimation."))); _u8L("This may cause problems in g-code visualization and printing time estimation."));
} }
BOOST_LOG_TRIVIAL(info) << "Exporting G-code..." << log_memory_info(); BOOST_LOG_TRIVIAL(info) << "Exporting G-code..." << log_memory_info();
@ -1111,7 +1106,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
} }
if (initial_extruder_id == static_cast<unsigned int>(-1)) if (initial_extruder_id == static_cast<unsigned int>(-1))
// No object to print was found, cancel the G-code export. // No object to print was found, cancel the G-code export.
throw Slic3r::SlicingError(_(L("No extrusions were generated for objects."))); throw Slic3r::SlicingError(_u8L("No extrusions were generated for objects."));
// We don't allow switching of extruders per layer by Model::custom_gcode_per_print_z in sequential mode. // We don't allow switching of extruders per layer by Model::custom_gcode_per_print_z in sequential mode.
// Use the extruder IDs collected from Regions. // Use the extruder IDs collected from Regions.
this->set_extruders(print.extruders()); this->set_extruders(print.extruders());
@ -1122,7 +1117,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
tool_ordering.assign_custom_gcodes(print); tool_ordering.assign_custom_gcodes(print);
if (tool_ordering.all_extruders().empty()) if (tool_ordering.all_extruders().empty())
// No object to print was found, cancel the G-code export. // No object to print was found, cancel the G-code export.
throw Slic3r::SlicingError(_(L("No extrusions were generated for objects."))); throw Slic3r::SlicingError(_u8L("No extrusions were generated for objects."));
has_wipe_tower = print.has_wipe_tower() && tool_ordering.has_wipe_tower(); has_wipe_tower = print.has_wipe_tower() && tool_ordering.has_wipe_tower();
initial_extruder_id = (has_wipe_tower && ! print.config().single_extruder_multi_material_priming) ? initial_extruder_id = (has_wipe_tower && ! print.config().single_extruder_multi_material_priming) ?
// The priming towers will be skipped. // The priming towers will be skipped.
@ -1316,8 +1311,8 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
// (See https://github.com/prusa3d/PrusaSlicer/issues/5441.) // (See https://github.com/prusa3d/PrusaSlicer/issues/5441.)
if (overlap) { if (overlap) {
print.active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL, print.active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL,
_(L("Your print is very close to the priming regions. " _u8L("Your print is very close to the priming regions. "
"Make sure there is no collision."))); "Make sure there is no collision."));
} else { } else {
// Just continue printing, no action necessary. // Just continue printing, no action necessary.
} }

View File

@ -185,11 +185,6 @@ static int run_script(const std::string &script, const std::string &gcode, std::
namespace Slic3r { namespace Slic3r {
//! macro used to mark string used at localization,
//! return same string
#define L(s) (s)
#define _(s) Slic3r::I18N::translate(s)
// Run post processing script / scripts if defined. // Run post processing script / scripts if defined.
// Returns true if a post-processing script was executed. // Returns true if a post-processing script was executed.
// Returns false if no post-processing script was defined. // Returns false if no post-processing script was defined.
@ -285,10 +280,10 @@ bool run_post_process_scripts(std::string &src_path, bool make_copy, const std::
throw Slic3r::RuntimeError(msg); throw Slic3r::RuntimeError(msg);
} }
if (! boost::filesystem::exists(gcode_file)) { if (! boost::filesystem::exists(gcode_file)) {
const std::string msg = (boost::format(_(L( const std::string msg = (boost::format(_u8L(
"Post-processing script %1% failed.\n\n" "Post-processing script %1% failed.\n\n"
"The post-processing script is expected to change the G-code file %2% in place, but the G-code file was deleted and likely saved under a new name.\n" "The post-processing script is expected to change the G-code file %2% in place, but the G-code file was deleted and likely saved under a new name.\n"
"Please adjust the post-processing script to change the G-code in place and consult the manual on how to optionally rename the post-processed G-code file.\n"))) "Please adjust the post-processing script to change the G-code in place and consult the manual on how to optionally rename the post-processed G-code file.\n"))
% script % path).str(); % script % path).str();
BOOST_LOG_TRIVIAL(error) << msg; BOOST_LOG_TRIVIAL(error) << msg;
throw Slic3r::RuntimeError(msg); throw Slic3r::RuntimeError(msg);

View File

@ -4,12 +4,17 @@
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include <numeric> #include <numeric>
#include <memory>
#include <sstream> #include <sstream>
#include <iomanip> #include <iomanip>
#include "ClipperUtils.hpp"
#include "GCodeProcessor.hpp" #include "GCodeProcessor.hpp"
#include "BoundingBox.hpp" #include "BoundingBox.hpp"
#include "LocalesUtils.hpp" #include "LocalesUtils.hpp"
#include "Geometry.hpp"
#include "Surface.hpp"
#include "Fill/FillRectilinear.hpp"
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
@ -512,6 +517,8 @@ WipeTower::WipeTower(const PrintConfig& config, const std::vector<std::vector<fl
m_wipe_tower_width(float(config.wipe_tower_width)), m_wipe_tower_width(float(config.wipe_tower_width)),
m_wipe_tower_rotation_angle(float(config.wipe_tower_rotation_angle)), m_wipe_tower_rotation_angle(float(config.wipe_tower_rotation_angle)),
m_wipe_tower_brim_width(float(config.wipe_tower_brim_width)), m_wipe_tower_brim_width(float(config.wipe_tower_brim_width)),
m_wipe_tower_cone_angle(float(config.wipe_tower_cone_angle)),
m_extra_spacing(float(config.wipe_tower_extra_spacing/100.)),
m_y_shift(0.f), m_y_shift(0.f),
m_z_pos(0.f), m_z_pos(0.f),
m_bridging(float(config.wipe_tower_bridging)), m_bridging(float(config.wipe_tower_bridging)),
@ -1169,45 +1176,171 @@ WipeTower::ToolChangeResult WipeTower::finish_layer()
";------------------\n\n\n\n\n\n\n"); ";------------------\n\n\n\n\n\n\n");
} }
// outer perimeter (always): const float spacing = m_perimeter_width - m_layer_height*float(1.-M_PI_4);
writer.rectangle(wt_box, feedrate);
// This block creates the stabilization cone.
// First define a lambda to draw the rectangle with stabilization.
auto supported_rectangle = [this, &writer, spacing](const box_coordinates& wt_box, double feedrate, bool infill_cone) -> Polygon {
const auto [R, support_scale] = get_wipe_tower_cone_base(m_wipe_tower_width, m_wipe_tower_height, m_wipe_tower_depth, m_wipe_tower_cone_angle);
double z = m_no_sparse_layers ? (m_current_height + m_layer_info->height) : m_layer_info->z; // the former should actually work in both cases, but let's stay on the safe side (the 2.6.0 is close)
double r = std::tan(Geometry::deg2rad(m_wipe_tower_cone_angle/2.f)) * (m_wipe_tower_height - z);
Vec2f center = (wt_box.lu + wt_box.rd) / 2.;
double w = wt_box.lu.y() - wt_box.ld.y();
enum Type {
Arc,
Corner,
ArcStart,
ArcEnd
};
// First generate vector of annotated point which form the boundary.
std::vector<std::pair<Vec2f, Type>> pts = {{wt_box.ru, Corner}};
if (double alpha_start = std::asin((0.5*w)/r); ! std::isnan(alpha_start) && r > 0.5*w+0.01) {
for (double alpha = alpha_start; alpha < M_PI-alpha_start+0.001; alpha+=(M_PI-2*alpha_start) / 20.)
pts.emplace_back(Vec2f(center.x() + r*std::cos(alpha)/support_scale, center.y() + r*std::sin(alpha)), alpha == alpha_start ? ArcStart : Arc);
pts.back().second = ArcEnd;
}
pts.emplace_back(wt_box.lu, Corner);
pts.emplace_back(wt_box.ld, Corner);
for (int i=int(pts.size())-3; i>0; --i)
pts.emplace_back(Vec2f(pts[i].first.x(), 2*center.y()-pts[i].first.y()), i == int(pts.size())-3 ? ArcStart : i == 1 ? ArcEnd : Arc);
pts.emplace_back(wt_box.rd, Corner);
// Create a Polygon from the points.
Polygon poly;
for (const auto& [pt, tag] : pts)
poly.points.push_back(Point::new_scale(pt));
// Prepare polygons to be filled by infill.
Polylines polylines;
if (infill_cone && m_wipe_tower_width > 2*spacing && m_wipe_tower_depth > 2*spacing) {
ExPolygons infill_areas;
ExPolygon wt_contour(poly);
Polygon wt_rectangle(Points{Point::new_scale(wt_box.ld), Point::new_scale(wt_box.rd), Point::new_scale(wt_box.ru), Point::new_scale(wt_box.lu)});
wt_rectangle = offset(wt_rectangle, scale_(-spacing/2.)).front();
wt_contour = offset_ex(wt_contour, scale_(-spacing/2.)).front();
infill_areas = diff_ex(wt_contour, wt_rectangle);
if (infill_areas.size() == 2) {
ExPolygon& bottom_expoly = infill_areas.front().contour.points.front().y() < infill_areas.back().contour.points.front().y() ? infill_areas[0] : infill_areas[1];
std::unique_ptr<Fill> filler(Fill::new_from_type(ipMonotonicLines));
filler->angle = Geometry::deg2rad(45.f);
filler->spacing = spacing;
FillParams params;
params.density = 1.f;
Surface surface(stBottom, bottom_expoly);
filler->bounding_box = get_extents(bottom_expoly);
polylines = filler->fill_surface(&surface, params);
if (! polylines.empty()) {
if (polylines.front().points.front().x() > polylines.back().points.back().x()) {
std::reverse(polylines.begin(), polylines.end());
for (Polyline& p : polylines)
p.reverse();
}
}
}
}
// Find the closest corner and travel to it.
int start_i = 0;
double min_dist = std::numeric_limits<double>::max();
for (int i=0; i<int(pts.size()); ++i) {
if (pts[i].second == Corner) {
double dist = (pts[i].first - Vec2f(writer.x(), writer.y())).squaredNorm();
if (dist < min_dist) {
min_dist = dist;
start_i = i;
}
}
}
writer.travel(pts[start_i].first);
// Now actually extrude the boundary (and possibly infill):
int i = start_i+1 == int(pts.size()) ? 0 : start_i + 1;
while (i != start_i) {
writer.extrude(pts[i].first, feedrate);
if (pts[i].second == ArcEnd) {
// Extrude the infill.
if (! polylines.empty()) {
// Extrude the infill and travel back to where we were.
bool mirror = ((pts[i].first.y() - center.y()) * (unscale(polylines.front().points.front()).y() - center.y())) < 0.;
for (const Polyline& line : polylines) {
writer.travel(center - (mirror ? 1.f : -1.f) * (unscale(line.points.front()).cast<float>() - center));
for (size_t i=0; i<line.points.size(); ++i)
writer.extrude(center - (mirror ? 1.f : -1.f) * (unscale(line.points[i]).cast<float>() - center));
}
writer.travel(pts[i].first);
}
}
if (++i == int(pts.size()))
i = 0;
}
writer.extrude(pts[start_i].first, feedrate);
return poly;
};
// outer contour (always)
bool infill_cone = first_layer && m_wipe_tower_width > 2*spacing && m_wipe_tower_depth > 2*spacing;
Polygon poly = supported_rectangle(wt_box, feedrate, infill_cone);
// brim (first layer only) // brim (first layer only)
if (first_layer) { if (first_layer) {
box_coordinates box = wt_box; box_coordinates box = wt_box;
float spacing = m_perimeter_width - m_layer_height*float(1.-M_PI_4);
// How many perimeters shall the brim have?
size_t loops_num = (m_wipe_tower_brim_width + spacing/2.f) / spacing; size_t loops_num = (m_wipe_tower_brim_width + spacing/2.f) / spacing;
for (size_t i = 0; i < loops_num; ++ i) { for (size_t i = 0; i < loops_num; ++ i) {
box.expand(spacing); poly = offset(poly, scale_(spacing)).front();
writer.rectangle(box); int cp = poly.closest_point_index(Point::new_scale(writer.x(), writer.y()));
writer.travel(unscale(poly.points[cp]).cast<float>());
for (int i=cp+1; true; ++i ) {
if (i==int(poly.points.size()))
i = 0;
writer.extrude(unscale(poly.points[i]).cast<float>());
if (i == cp)
break;
}
} }
// Save actual brim width to be later passed to the Print object, which will use it // Save actual brim width to be later passed to the Print object, which will use it
// for skirt calculation and pass it to GLCanvas for precise preview box // for skirt calculation and pass it to GLCanvas for precise preview box
m_wipe_tower_brim_width_real = wt_box.ld.x() - box.ld.x() + spacing/2.f; m_wipe_tower_brim_width_real = loops_num * spacing;
wt_box = box;
} }
// Now prepare future wipe. box contains rectangle that was extruded last (ccw). // Now prepare future wipe.
Vec2f target = (writer.pos() == wt_box.ld ? wt_box.rd : int i = poly.closest_point_index(Point::new_scale(writer.x(), writer.y()));
(writer.pos() == wt_box.rd ? wt_box.ru : writer.add_wipe_point(writer.pos());
(writer.pos() == wt_box.ru ? wt_box.lu : writer.add_wipe_point(unscale(poly.points[i==0 ? int(poly.points.size())-1 : i-1]).cast<float>());
wt_box.ld)));
writer.add_wipe_point(writer.pos())
.add_wipe_point(target);
// Ask our writer about how much material was consumed. // Ask our writer about how much material was consumed.
// Skip this in case the layer is sparse and config option to not print sparse layers is enabled. // Skip this in case the layer is sparse and config option to not print sparse layers is enabled.
if (! m_no_sparse_layers || toolchanges_on_layer || first_layer) if (! m_no_sparse_layers || toolchanges_on_layer || first_layer) {
if (m_current_tool < m_used_filament_length.size()) if (m_current_tool < m_used_filament_length.size())
m_used_filament_length[m_current_tool] += writer.get_and_reset_used_filament_length(); m_used_filament_length[m_current_tool] += writer.get_and_reset_used_filament_length();
m_current_height += m_layer_info->height;
}
return construct_tcr(writer, false, old_tool); return construct_tcr(writer, false, old_tool);
} }
// Static method to get the radius and x-scaling of the stabilizing cone base.
std::pair<double, double> WipeTower::get_wipe_tower_cone_base(double width, double height, double depth, double angle_deg)
{
double R = std::tan(Geometry::deg2rad(angle_deg/2.)) * height;
double fake_width = 0.66 * width;
double diag = std::hypot(fake_width / 2., depth / 2.);
double support_scale = 1.;
if (R > diag) {
double w = fake_width;
double sin = 0.5 * depth / diag;
double tan = depth / w;
double t = (R - diag) * sin;
support_scale = (w / 2. + t / tan + t * tan) / (w / 2.);
}
return std::make_pair(R, support_scale);
}
// Appends a toolchange into m_plan and calculates neccessary depth of the corresponding box // Appends a toolchange into m_plan and calculates neccessary depth of the corresponding box
void WipeTower::plan_toolchange(float z_par, float layer_height_par, unsigned int old_tool, void WipeTower::plan_toolchange(float z_par, float layer_height_par, unsigned int old_tool,
unsigned int new_tool, float wipe_volume) unsigned int new_tool, float wipe_volume)
@ -1250,6 +1383,8 @@ void WipeTower::plan_tower()
m_wipe_tower_depth = 0.f; m_wipe_tower_depth = 0.f;
for (auto& layer : m_plan) for (auto& layer : m_plan)
layer.depth = 0.f; layer.depth = 0.f;
m_wipe_tower_height = m_plan.empty() ? 0.f : m_plan.back().z;
m_current_height = 0.f;
for (int layer_index = int(m_plan.size()) - 1; layer_index >= 0; --layer_index) for (int layer_index = int(m_plan.size()) - 1; layer_index >= 0; --layer_index)
{ {
@ -1334,8 +1469,6 @@ void WipeTower::generate(std::vector<std::vector<WipeTower::ToolChangeResult>> &
if (m_plan.empty()) if (m_plan.empty())
return; return;
m_extra_spacing = 1.f;
plan_tower(); plan_tower();
for (int i=0;i<5;++i) { for (int i=0;i<5;++i) {
save_on_last_wipe(); save_on_last_wipe();
@ -1343,6 +1476,7 @@ void WipeTower::generate(std::vector<std::vector<WipeTower::ToolChangeResult>> &
} }
m_layer_info = m_plan.begin(); m_layer_info = m_plan.begin();
m_current_height = 0.f;
// we don't know which extruder to start with - we'll set it according to the first toolchange // we don't know which extruder to start with - we'll set it according to the first toolchange
for (const auto& layer : m_plan) { for (const auto& layer : m_plan) {
@ -1358,7 +1492,7 @@ void WipeTower::generate(std::vector<std::vector<WipeTower::ToolChangeResult>> &
m_old_temperature = -1; // reset last temperature written in the gcode m_old_temperature = -1; // reset last temperature written in the gcode
std::vector<WipeTower::ToolChangeResult> layer_result; std::vector<WipeTower::ToolChangeResult> layer_result;
for (auto layer : m_plan) for (const WipeTower::WipeTowerInfo& layer : m_plan)
{ {
set_layer(layer.z, layer.height, 0, false/*layer.z == m_plan.front().z*/, layer.z == m_plan.back().z); set_layer(layer.z, layer.height, 0, false/*layer.z == m_plan.front().z*/, layer.z == m_plan.back().z);
m_internal_rotation += 180.f; m_internal_rotation += 180.f;

View File

@ -23,6 +23,8 @@ class WipeTower
public: public:
static const std::string never_skip_tag() { return "_GCODE_WIPE_TOWER_NEVER_SKIP_TAG"; } static const std::string never_skip_tag() { return "_GCODE_WIPE_TOWER_NEVER_SKIP_TAG"; }
static std::pair<double, double> get_wipe_tower_cone_base(double width, double height, double depth, double angle_deg);
struct Extrusion struct Extrusion
{ {
Extrusion(const Vec2f &pos, float width, unsigned int tool) : pos(pos), width(width), tool(tool) {} Extrusion(const Vec2f &pos, float width, unsigned int tool) : pos(pos), width(width), tool(tool) {}
@ -142,6 +144,7 @@ public:
float get_depth() const { return m_wipe_tower_depth; } float get_depth() const { return m_wipe_tower_depth; }
float get_brim_width() const { return m_wipe_tower_brim_width_real; } float get_brim_width() const { return m_wipe_tower_brim_width_real; }
float get_wipe_tower_height() const { return m_wipe_tower_height; }
@ -253,6 +256,8 @@ private:
Vec2f m_wipe_tower_pos; // Left front corner of the wipe tower in mm. Vec2f m_wipe_tower_pos; // Left front corner of the wipe tower in mm.
float m_wipe_tower_width; // Width of the wipe tower. float m_wipe_tower_width; // Width of the wipe tower.
float m_wipe_tower_depth = 0.f; // Depth of the wipe tower float m_wipe_tower_depth = 0.f; // Depth of the wipe tower
float m_wipe_tower_height = 0.f;
float m_wipe_tower_cone_angle = 0.f;
float m_wipe_tower_brim_width = 0.f; // Width of brim (mm) from config float m_wipe_tower_brim_width = 0.f; // Width of brim (mm) from config
float m_wipe_tower_brim_width_real = 0.f; // Width of brim (mm) after generation float m_wipe_tower_brim_width_real = 0.f; // Width of brim (mm) after generation
float m_wipe_tower_rotation_angle = 0.f; // Wipe tower rotation angle in degrees (with respect to x axis) float m_wipe_tower_rotation_angle = 0.f; // Wipe tower rotation angle in degrees (with respect to x axis)
@ -359,6 +364,10 @@ private:
std::vector<WipeTowerInfo> m_plan; // Stores information about all layers and toolchanges for the future wipe tower (filled by plan_toolchange(...)) std::vector<WipeTowerInfo> m_plan; // Stores information about all layers and toolchanges for the future wipe tower (filled by plan_toolchange(...))
std::vector<WipeTowerInfo>::iterator m_layer_info = m_plan.end(); std::vector<WipeTowerInfo>::iterator m_layer_info = m_plan.end();
// This sums height of all extruded layers, not counting the layers which
// will be later removed when the "no_sparse_layers" is used.
float m_current_height = 0.f;
// Stores information about used filament length per extruder: // Stores information about used filament length per extruder:
std::vector<float> m_used_filament_length; std::vector<float> m_used_filament_length;

View File

@ -128,7 +128,7 @@ inline static Linef make_linef(const VD::edge_type &edge)
return {Vec2d(v0->x(), v0->y()), Vec2d(v1->x(), v1->y())}; return {Vec2d(v0->x(), v0->y()), Vec2d(v1->x(), v1->y())};
} }
inline static bool is_equal(const VD::vertex_type &first, const VD::vertex_type &second) { return first.x() == second.x() && first.y() == second.y(); } [[maybe_unused]] inline static bool is_equal(const VD::vertex_type &first, const VD::vertex_type &second) { return first.x() == second.x() && first.y() == second.y(); }
// FIXME Lukas H.: Also includes parabolic segments. // FIXME Lukas H.: Also includes parabolic segments.
bool VoronoiUtilsCgal::is_voronoi_diagram_planar_intersection(const VD &voronoi_diagram) bool VoronoiUtilsCgal::is_voronoi_diagram_planar_intersection(const VD &voronoi_diagram)

View File

@ -3,6 +3,12 @@
#include <string> #include <string>
#ifdef SLIC3R_CURRENTLY_COMPILING_GUI_MODULE
#ifndef SLIC3R_ALLOW_LIBSLIC3R_I18N_IN_SLIC3R
#error You included libslic3r/I18N.hpp into a file belonging to slic3r module.
#endif
#endif
namespace Slic3r { namespace Slic3r {
namespace I18N { namespace I18N {
@ -15,4 +21,17 @@ namespace I18N {
} // namespace Slic3r } // namespace Slic3r
// When this is included from slic3r, better do not define the translation functions.
// Macros from slic3r/GUI/I18N.hpp should be used there.
#ifndef SLIC3R_CURRENTLY_COMPILING_GUI_MODULE
#ifdef L
#error L macro is defined where it shouldn't be. Didn't you include slic3r/GUI/I18N.hpp in libslic3r by mistake?
#endif
namespace {
const char* L(const char* s) { return s; }
const char* L_CONTEXT(const char* s, const char* context) { return s; }
std::string _u8L(const char* s) { return Slic3r::I18N::translate(s); }
}
#endif
#endif /* slic3r_I18N_hpp_ */ #endif /* slic3r_I18N_hpp_ */

File diff suppressed because it is too large Load Diff

View File

@ -10,15 +10,6 @@
#include <Windows.h> #include <Windows.h>
#endif /* _MSC_VER */ #endif /* _MSC_VER */
// instead of #include "slic3r/GUI/I18N.hpp" :
#ifndef L
// !!! If you needed to translate some string,
// !!! please use _L(string)
// !!! _() - is a standard wxWidgets macro to translate
// !!! L() is used only for marking localizable string
// !!! It will be used in "xgettext" to create a Locating Message Catalog.
#define L(s) s
#endif /* L */
#include <algorithm> #include <algorithm>
#include <fstream> #include <fstream>
@ -460,8 +451,8 @@ static std::vector<std::string> s_Preset_print_options {
"perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width", "perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width",
"top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "infill_anchor", "infill_anchor_max", "bridge_flow_ratio", "top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "infill_anchor", "infill_anchor_max", "bridge_flow_ratio",
"elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "gcode_resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y", "elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "gcode_resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y",
"wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_bridging", "single_extruder_multi_material_priming", "mmu_segmented_region_max_width", "wipe_tower_width", "wipe_tower_cone_angle", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_bridging", "single_extruder_multi_material_priming", "mmu_segmented_region_max_width",
"wipe_tower_no_sparse_layers", "compatible_printers", "compatible_printers_condition", "inherits", "wipe_tower_no_sparse_layers", "wipe_tower_extra_spacing", "compatible_printers", "compatible_printers_condition", "inherits",
"perimeter_generator", "wall_transition_length", "wall_transition_filter_deviation", "wall_transition_angle", "perimeter_generator", "wall_transition_length", "wall_transition_filter_deviation", "wall_transition_angle",
"wall_distribution_count", "min_feature_size", "min_bead_width" "wall_distribution_count", "min_feature_size", "min_bead_width"
}; };

View File

@ -27,8 +27,6 @@
#include <boost/log/trivial.hpp> #include <boost/log/trivial.hpp>
#include <boost/regex.hpp> #include <boost/regex.hpp>
// Mark string for localization and translate.
#define L(s) Slic3r::I18N::translate(s)
namespace Slic3r { namespace Slic3r {
@ -205,7 +203,9 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|| opt_key == "wipe_tower" || opt_key == "wipe_tower"
|| opt_key == "wipe_tower_width" || opt_key == "wipe_tower_width"
|| opt_key == "wipe_tower_brim_width" || opt_key == "wipe_tower_brim_width"
|| opt_key == "wipe_tower_cone_angle"
|| opt_key == "wipe_tower_bridging" || opt_key == "wipe_tower_bridging"
|| opt_key == "wipe_tower_extra_spacing"
|| opt_key == "wipe_tower_no_sparse_layers" || opt_key == "wipe_tower_no_sparse_layers"
|| opt_key == "wiping_volumes_matrix" || opt_key == "wiping_volumes_matrix"
|| opt_key == "parking_pos_retraction" || opt_key == "parking_pos_retraction"
@ -472,20 +472,20 @@ std::string Print::validate(std::string* warning) const
std::vector<unsigned int> extruders = this->extruders(); std::vector<unsigned int> extruders = this->extruders();
if (m_objects.empty()) if (m_objects.empty())
return L("All objects are outside of the print volume."); return _u8L("All objects are outside of the print volume.");
if (extruders.empty()) if (extruders.empty())
return L("The supplied settings will cause an empty print."); return _u8L("The supplied settings will cause an empty print.");
if (m_config.complete_objects) { if (m_config.complete_objects) {
if (! sequential_print_horizontal_clearance_valid(*this)) if (! sequential_print_horizontal_clearance_valid(*this))
return L("Some objects are too close; your extruder will collide with them."); return _u8L("Some objects are too close; your extruder will collide with them.");
if (! sequential_print_vertical_clearance_valid(*this)) if (! sequential_print_vertical_clearance_valid(*this))
return L("Some objects are too tall and cannot be printed without extruder collisions."); return _u8L("Some objects are too tall and cannot be printed without extruder collisions.");
} }
if (m_config.avoid_crossing_perimeters && m_config.avoid_crossing_curled_overhangs) { if (m_config.avoid_crossing_perimeters && m_config.avoid_crossing_curled_overhangs) {
return L("Avoid crossing perimeters option and avoid crossing curled overhangs option cannot be both enabled together."); return _u8L("Avoid crossing perimeters option and avoid crossing curled overhangs option cannot be both enabled together.");
} }
if (m_config.spiral_vase) { if (m_config.spiral_vase) {
@ -494,11 +494,11 @@ std::string Print::validate(std::string* warning) const
total_copies_count += object->instances().size(); total_copies_count += object->instances().size();
// #4043 // #4043
if (total_copies_count > 1 && ! m_config.complete_objects.value) if (total_copies_count > 1 && ! m_config.complete_objects.value)
return L("Only a single object may be printed at a time in Spiral Vase mode. " return _u8L("Only a single object may be printed at a time in Spiral Vase mode. "
"Either remove all but the last object, or enable sequential mode by \"complete_objects\"."); "Either remove all but the last object, or enable sequential mode by \"complete_objects\".");
assert(m_objects.size() == 1); assert(m_objects.size() == 1);
if (m_objects.front()->all_regions().size() > 1) if (m_objects.front()->all_regions().size() > 1)
return L("The Spiral Vase option can only be used when printing single material objects."); return _u8L("The Spiral Vase option can only be used when printing single material objects.");
} }
// Cache of layer height profiles for checking: // Cache of layer height profiles for checking:
@ -522,7 +522,7 @@ std::string Print::validate(std::string* warning) const
//FIXME It is quite expensive to generate object layers just to get the print height! //FIXME It is quite expensive to generate object layers just to get the print height!
if (auto layers = generate_object_layers(print_object.slicing_parameters(), layer_height_profile(print_object_idx)); if (auto layers = generate_object_layers(print_object.slicing_parameters(), layer_height_profile(print_object_idx));
! layers.empty() && layers.back() > this->config().max_print_height + EPSILON) { ! layers.empty() && layers.back() > this->config().max_print_height + EPSILON) {
return L("The print is taller than the maximum allowed height. You might want to reduce the size of your model" return _u8L("The print is taller than the maximum allowed height. You might want to reduce the size of your model"
" or change current print settings and retry."); " or change current print settings and retry.");
} }
} }
@ -539,7 +539,7 @@ std::string Print::validate(std::string* warning) const
print_object.model_object()->has_custom_layering()) { print_object.model_object()->has_custom_layering()) {
if (const std::vector<coordf_t> &layers = layer_height_profile(print_object_idx); ! layers.empty()) if (const std::vector<coordf_t> &layers = layer_height_profile(print_object_idx); ! layers.empty())
if (! check_object_layers_fixed(print_object.slicing_parameters(), layers)) if (! check_object_layers_fixed(print_object.slicing_parameters(), layers))
return L("Variable layer height is not supported with Organic supports."); return _u8L("Variable layer height is not supported with Organic supports.");
} }
if (this->has_wipe_tower() && ! m_objects.empty()) { if (this->has_wipe_tower() && ! m_objects.empty()) {
@ -552,21 +552,21 @@ std::string Print::validate(std::string* warning) const
double filament_diam = m_config.filament_diameter.get_at(extruder_idx); double filament_diam = m_config.filament_diameter.get_at(extruder_idx);
if (nozzle_diam - EPSILON > first_nozzle_diam || nozzle_diam + EPSILON < first_nozzle_diam if (nozzle_diam - EPSILON > first_nozzle_diam || nozzle_diam + EPSILON < first_nozzle_diam
|| std::abs((filament_diam-first_filament_diam)/first_filament_diam) > 0.1) || std::abs((filament_diam-first_filament_diam)/first_filament_diam) > 0.1)
return L("The wipe tower is only supported if all extruders have the same nozzle diameter " return _u8L("The wipe tower is only supported if all extruders have the same nozzle diameter "
"and use filaments of the same diameter."); "and use filaments of the same diameter.");
} }
if (m_config.gcode_flavor != gcfRepRapSprinter && m_config.gcode_flavor != gcfRepRapFirmware && if (m_config.gcode_flavor != gcfRepRapSprinter && m_config.gcode_flavor != gcfRepRapFirmware &&
m_config.gcode_flavor != gcfRepetier && m_config.gcode_flavor != gcfMarlinLegacy && m_config.gcode_flavor != gcfMarlinFirmware) m_config.gcode_flavor != gcfRepetier && m_config.gcode_flavor != gcfMarlinLegacy && m_config.gcode_flavor != gcfMarlinFirmware)
return L("The Wipe Tower is currently only supported for the Marlin, RepRap/Sprinter, RepRapFirmware and Repetier G-code flavors."); return _u8L("The Wipe Tower is currently only supported for the Marlin, RepRap/Sprinter, RepRapFirmware and Repetier G-code flavors.");
if (! m_config.use_relative_e_distances) if (! m_config.use_relative_e_distances)
return L("The Wipe Tower is currently only supported with the relative extruder addressing (use_relative_e_distances=1)."); return _u8L("The Wipe Tower is currently only supported with the relative extruder addressing (use_relative_e_distances=1).");
if (m_config.ooze_prevention && m_config.single_extruder_multi_material) if (m_config.ooze_prevention && m_config.single_extruder_multi_material)
return L("Ooze prevention is only supported with the wipe tower when 'single_extruder_multi_material' is off."); return _u8L("Ooze prevention is only supported with the wipe tower when 'single_extruder_multi_material' is off.");
if (m_config.use_volumetric_e) if (m_config.use_volumetric_e)
return L("The Wipe Tower currently does not support volumetric E (use_volumetric_e=0)."); return _u8L("The Wipe Tower currently does not support volumetric E (use_volumetric_e=0).");
if (m_config.complete_objects && extruders.size() > 1) if (m_config.complete_objects && extruders.size() > 1)
return L("The Wipe Tower is currently not supported for multimaterial sequential prints."); return _u8L("The Wipe Tower is currently not supported for multimaterial sequential prints.");
if (m_objects.size() > 1) { if (m_objects.size() > 1) {
const SlicingParameters &slicing_params0 = m_objects.front()->slicing_parameters(); const SlicingParameters &slicing_params0 = m_objects.front()->slicing_parameters();
@ -576,21 +576,21 @@ std::string Print::validate(std::string* warning) const
const SlicingParameters &slicing_params = object->slicing_parameters(); const SlicingParameters &slicing_params = object->slicing_parameters();
if (std::abs(slicing_params.first_print_layer_height - slicing_params0.first_print_layer_height) > EPSILON || if (std::abs(slicing_params.first_print_layer_height - slicing_params0.first_print_layer_height) > EPSILON ||
std::abs(slicing_params.layer_height - slicing_params0.layer_height ) > EPSILON) std::abs(slicing_params.layer_height - slicing_params0.layer_height ) > EPSILON)
return L("The Wipe Tower is only supported for multiple objects if they have equal layer heights"); return _u8L("The Wipe Tower is only supported for multiple objects if they have equal layer heights");
if (slicing_params.raft_layers() != slicing_params0.raft_layers()) if (slicing_params.raft_layers() != slicing_params0.raft_layers())
return L("The Wipe Tower is only supported for multiple objects if they are printed over an equal number of raft layers"); return _u8L("The Wipe Tower is only supported for multiple objects if they are printed over an equal number of raft layers");
if (slicing_params0.gap_object_support != slicing_params.gap_object_support || if (slicing_params0.gap_object_support != slicing_params.gap_object_support ||
slicing_params0.gap_support_object != slicing_params.gap_support_object) slicing_params0.gap_support_object != slicing_params.gap_support_object)
return L("The Wipe Tower is only supported for multiple objects if they are printed with the same support_material_contact_distance"); return _u8L("The Wipe Tower is only supported for multiple objects if they are printed with the same support_material_contact_distance");
if (! equal_layering(slicing_params, slicing_params0)) if (! equal_layering(slicing_params, slicing_params0))
return L("The Wipe Tower is only supported for multiple objects if they are sliced equally."); return _u8L("The Wipe Tower is only supported for multiple objects if they are sliced equally.");
if (has_custom_layering) { if (has_custom_layering) {
auto &lh = layer_height_profile(i); auto &lh = layer_height_profile(i);
auto &lh_tallest = layer_height_profile(tallest_object_idx); auto &lh_tallest = layer_height_profile(tallest_object_idx);
if (*(lh.end()-2) > *(lh_tallest.end()-2)) if (*(lh.end()-2) > *(lh_tallest.end()-2))
tallest_object_idx = i; tallest_object_idx = i;
} }
} }
if (has_custom_layering) { if (has_custom_layering) {
for (size_t idx_object = 0; idx_object < m_objects.size(); ++ idx_object) { for (size_t idx_object = 0; idx_object < m_objects.size(); ++ idx_object) {
@ -608,7 +608,7 @@ std::string Print::validate(std::string* warning) const
if (i%2 == 0 && layer_height_profiles[tallest_object_idx][i] > layer_height_profiles[idx_object][layer_height_profiles[idx_object].size() - 2 ]) if (i%2 == 0 && layer_height_profiles[tallest_object_idx][i] > layer_height_profiles[idx_object][layer_height_profiles[idx_object].size() - 2 ])
break; break;
if (std::abs(layer_height_profiles[idx_object][i] - layer_height_profiles[tallest_object_idx][i]) > eps) if (std::abs(layer_height_profiles[idx_object][i] - layer_height_profiles[tallest_object_idx][i]) > eps)
return L("The Wipe tower is only supported if all objects have the same variable layer height"); return _u8L("The Wipe tower is only supported if all objects have the same variable layer height");
++i; ++i;
} }
} }
@ -632,7 +632,7 @@ std::string Print::validate(std::string* warning) const
unsigned int total_extruders_count = m_config.nozzle_diameter.size(); unsigned int total_extruders_count = m_config.nozzle_diameter.size();
for (const auto& extruder_idx : extruders) for (const auto& extruder_idx : extruders)
if ( extruder_idx >= total_extruders_count ) if ( extruder_idx >= total_extruders_count )
return L("One or more object were assigned an extruder that the printer does not have."); return _u8L("One or more object were assigned an extruder that the printer does not have.");
#endif #endif
auto validate_extrusion_width = [/*min_nozzle_diameter,*/ max_nozzle_diameter](const ConfigBase &config, const char *opt_key, double layer_height, std::string &err_msg) -> bool { auto validate_extrusion_width = [/*min_nozzle_diameter,*/ max_nozzle_diameter](const ConfigBase &config, const char *opt_key, double layer_height, std::string &err_msg) -> bool {
@ -645,10 +645,10 @@ std::string Print::validate(std::string* warning) const
if (extrusion_width_min == 0) { if (extrusion_width_min == 0) {
// Default "auto-generated" extrusion width is always valid. // Default "auto-generated" extrusion width is always valid.
} else if (extrusion_width_min <= layer_height) { } else if (extrusion_width_min <= layer_height) {
err_msg = (boost::format(L("%1%=%2% mm is too low to be printable at a layer height %3% mm")) % opt_key % extrusion_width_min % layer_height).str(); err_msg = (boost::format(_u8L("%1%=%2% mm is too low to be printable at a layer height %3% mm")) % opt_key % extrusion_width_min % layer_height).str();
return false; return false;
} else if (extrusion_width_max >= max_nozzle_diameter * 3.) { } else if (extrusion_width_max >= max_nozzle_diameter * 3.) {
err_msg = (boost::format(L("Excessive %1%=%2% mm to be printable with a nozzle diameter %3% mm")) % opt_key % extrusion_width_max % max_nozzle_diameter).str(); err_msg = (boost::format(_u8L("Excessive %1%=%2% mm to be printable with a nozzle diameter %3% mm")) % opt_key % extrusion_width_max % max_nozzle_diameter).str();
return false; return false;
} }
return true; return true;
@ -659,7 +659,7 @@ std::string Print::validate(std::string* warning) const
// The object has some form of support and either support_material_extruder or support_material_interface_extruder // The object has some form of support and either support_material_extruder or support_material_interface_extruder
// will be printed with the current tool without a forced tool change. Play safe, assert that all object nozzles // will be printed with the current tool without a forced tool change. Play safe, assert that all object nozzles
// are of the same diameter. // are of the same diameter.
return L("Printing with multiple extruders of differing nozzle diameters. " return _u8L("Printing with multiple extruders of differing nozzle diameters. "
"If support is to be printed with the current extruder (support_material_extruder == 0 or support_material_interface_extruder == 0), " "If support is to be printed with the current extruder (support_material_extruder == 0 or support_material_interface_extruder == 0), "
"all nozzles have to be of the same diameter."); "all nozzles have to be of the same diameter.");
} }
@ -667,11 +667,11 @@ std::string Print::validate(std::string* warning) const
if (object->config().support_material_contact_distance == 0) { if (object->config().support_material_contact_distance == 0) {
// Soluble interface // Soluble interface
if (! object->config().support_material_synchronize_layers) if (! object->config().support_material_synchronize_layers)
return L("For the Wipe Tower to work with the soluble supports, the support layers need to be synchronized with the object layers."); return _u8L("For the Wipe Tower to work with the soluble supports, the support layers need to be synchronized with the object layers.");
} else { } else {
// Non-soluble interface // Non-soluble interface
if (object->config().support_material_extruder != 0 || object->config().support_material_interface_extruder != 0) if (object->config().support_material_extruder != 0 || object->config().support_material_interface_extruder != 0)
return L("The Wipe Tower currently supports the non-soluble supports only if they are printed with the current extruder without triggering a tool change. " return _u8L("The Wipe Tower currently supports the non-soluble supports only if they are printed with the current extruder without triggering a tool change. "
"(both support_material_extruder and support_material_interface_extruder need to be set to 0)."); "(both support_material_extruder and support_material_interface_extruder need to be set to 0).");
} }
} }
@ -707,12 +707,12 @@ std::string Print::validate(std::string* warning) const
first_layer_min_nozzle_diameter = min_nozzle_diameter; first_layer_min_nozzle_diameter = min_nozzle_diameter;
} }
if (first_layer_height > first_layer_min_nozzle_diameter) if (first_layer_height > first_layer_min_nozzle_diameter)
return L("First layer height can't be greater than nozzle diameter"); return _u8L("First layer height can't be greater than nozzle diameter");
// validate layer_height // validate layer_height
double layer_height = object->config().layer_height.value; double layer_height = object->config().layer_height.value;
if (layer_height > min_nozzle_diameter) if (layer_height > min_nozzle_diameter)
return L("Layer height can't be greater than nozzle diameter"); return _u8L("Layer height can't be greater than nozzle diameter");
// Validate extrusion widths. // Validate extrusion widths.
std::string err_msg; std::string err_msg;
@ -733,11 +733,11 @@ std::string Print::validate(std::string* warning) const
// See GH issues #6336 #5073 // See GH issues #6336 #5073
if ((m_config.gcode_flavor == gcfMarlinLegacy || m_config.gcode_flavor == gcfMarlinFirmware) && if ((m_config.gcode_flavor == gcfMarlinLegacy || m_config.gcode_flavor == gcfMarlinFirmware) &&
! before_layer_gcode_resets_extruder && ! layer_gcode_resets_extruder) ! before_layer_gcode_resets_extruder && ! layer_gcode_resets_extruder)
return L("Relative extruder addressing requires resetting the extruder position at each layer to prevent loss of floating point accuracy. Add \"G92 E0\" to layer_gcode."); return _u8L("Relative extruder addressing requires resetting the extruder position at each layer to prevent loss of floating point accuracy. Add \"G92 E0\" to layer_gcode.");
} else if (before_layer_gcode_resets_extruder) } else if (before_layer_gcode_resets_extruder)
return L("\"G92 E0\" was found in before_layer_gcode, which is incompatible with absolute extruder addressing."); return _u8L("\"G92 E0\" was found in before_layer_gcode, which is incompatible with absolute extruder addressing.");
else if (layer_gcode_resets_extruder) else if (layer_gcode_resets_extruder)
return L("\"G92 E0\" was found in layer_gcode, which is incompatible with absolute extruder addressing."); return _u8L("\"G92 E0\" was found in layer_gcode, which is incompatible with absolute extruder addressing.");
} }
return std::string(); return std::string();
@ -879,7 +879,7 @@ void Print::process()
BOOST_LOG_TRIVIAL(info) << "Starting the slicing process." << log_memory_info(); BOOST_LOG_TRIVIAL(info) << "Starting the slicing process." << log_memory_info();
for (PrintObject *obj : m_objects) for (PrintObject *obj : m_objects)
obj->make_perimeters(); obj->make_perimeters();
this->set_status(70, L("Infilling layers")); this->set_status(70, _u8L("Infilling layers"));
for (PrintObject *obj : m_objects) for (PrintObject *obj : m_objects)
obj->infill(); obj->infill();
for (PrintObject *obj : m_objects) for (PrintObject *obj : m_objects)
@ -896,7 +896,7 @@ void Print::process()
m_wipe_tower_data.clear(); m_wipe_tower_data.clear();
m_tool_ordering.clear(); m_tool_ordering.clear();
if (this->has_wipe_tower()) { if (this->has_wipe_tower()) {
//this->set_status(95, L("Generating wipe tower")); //this->set_status(95, _u8L("Generating wipe tower"));
this->_make_wipe_tower(); this->_make_wipe_tower();
} else if (! this->config().complete_objects.value) { } else if (! this->config().complete_objects.value) {
// Initialize the tool ordering, so it could be used by the G-code preview slider for planning tool changes and filament switches. // Initialize the tool ordering, so it could be used by the G-code preview slider for planning tool changes and filament switches.
@ -907,7 +907,7 @@ void Print::process()
this->set_done(psWipeTower); this->set_done(psWipeTower);
} }
if (this->set_started(psSkirtBrim)) { if (this->set_started(psSkirtBrim)) {
this->set_status(88, L("Generating skirt and brim")); this->set_status(88, _u8L("Generating skirt and brim"));
m_skirt.clear(); m_skirt.clear();
m_skirt_convex_hull.clear(); m_skirt_convex_hull.clear();
@ -955,11 +955,11 @@ std::string Print::export_gcode(const std::string& path_template, GCodeProcessor
std::string message; std::string message;
if (!path.empty() && result == nullptr) { if (!path.empty() && result == nullptr) {
// Only show the path if preview_data is not set -> running from command line. // Only show the path if preview_data is not set -> running from command line.
message = L("Exporting G-code"); message = _u8L("Exporting G-code");
message += " to "; message += " to ";
message += path; message += path;
} else } else
message = L("Generating G-code"); message = _u8L("Generating G-code");
this->set_status(90, message); this->set_status(90, message);
// Create GCode on heap, it has quite a lot of data. // Create GCode on heap, it has quite a lot of data.
@ -1133,23 +1133,34 @@ Polygons Print::first_layer_islands() const
std::vector<Point> Print::first_layer_wipe_tower_corners() const std::vector<Point> Print::first_layer_wipe_tower_corners() const
{ {
std::vector<Point> corners; std::vector<Point> pts_scaled;
if (has_wipe_tower() && ! m_wipe_tower_data.tool_changes.empty()) { if (has_wipe_tower() && ! m_wipe_tower_data.tool_changes.empty()) {
double width = m_config.wipe_tower_width + 2*m_wipe_tower_data.brim_width; double width = m_config.wipe_tower_width + 2*m_wipe_tower_data.brim_width;
double depth = m_wipe_tower_data.depth + 2*m_wipe_tower_data.brim_width; double depth = m_wipe_tower_data.depth + 2*m_wipe_tower_data.brim_width;
Vec2d pt0(-m_wipe_tower_data.brim_width, -m_wipe_tower_data.brim_width); Vec2d pt0(-m_wipe_tower_data.brim_width, -m_wipe_tower_data.brim_width);
for (Vec2d pt : {
pt0, // First the corners.
Vec2d(pt0.x()+width, pt0.y() ), std::vector<Vec2d> pts = { pt0,
Vec2d(pt0.x()+width, pt0.y()+depth), Vec2d(pt0.x()+width, pt0.y()),
Vec2d(pt0.x(), pt0.y()+depth) Vec2d(pt0.x()+width, pt0.y()+depth),
}) { Vec2d(pt0.x(),pt0.y()+depth)
};
// Now the stabilization cone.
Vec2d center = (pts[0] + pts[2])/2.;
const auto [cone_R, cone_x_scale] = WipeTower::get_wipe_tower_cone_base(m_config.wipe_tower_width, m_wipe_tower_data.height, m_wipe_tower_data.depth, m_config.wipe_tower_cone_angle);
double r = cone_R + m_wipe_tower_data.brim_width;
for (double alpha = 0.; alpha<2*M_PI; alpha += M_PI/20.)
pts.emplace_back(center + r*Vec2d(std::cos(alpha)/cone_x_scale, std::sin(alpha)));
for (Vec2d& pt : pts) {
pt = Eigen::Rotation2Dd(Geometry::deg2rad(m_config.wipe_tower_rotation_angle.value)) * pt; pt = Eigen::Rotation2Dd(Geometry::deg2rad(m_config.wipe_tower_rotation_angle.value)) * pt;
pt += Vec2d(m_config.wipe_tower_x.value, m_config.wipe_tower_y.value); pt += Vec2d(m_config.wipe_tower_x.value, m_config.wipe_tower_y.value);
corners.emplace_back(Point(scale_(pt.x()), scale_(pt.y()))); pts_scaled.emplace_back(Point(scale_(pt.x()), scale_(pt.y())));
} }
} }
return corners; return pts_scaled;
} }
void Print::finalize_first_layer_convex_hull() void Print::finalize_first_layer_convex_hull()
@ -1168,30 +1179,30 @@ void Print::alert_when_supports_needed()
{ {
if (this->set_started(psAlertWhenSupportsNeeded)) { if (this->set_started(psAlertWhenSupportsNeeded)) {
BOOST_LOG_TRIVIAL(debug) << "psAlertWhenSupportsNeeded - start"; BOOST_LOG_TRIVIAL(debug) << "psAlertWhenSupportsNeeded - start";
set_status(69, L("Alert if supports needed")); set_status(69, _u8L("Alert if supports needed"));
auto issue_to_alert_message = [](SupportSpotsGenerator::SupportPointCause cause, bool critical) { auto issue_to_alert_message = [](SupportSpotsGenerator::SupportPointCause cause, bool critical) {
std::string message; std::string message;
switch (cause) { switch (cause) {
//TRN Alert when support is needed. Describes that the model has long bridging extrusions which may print badly //TRN Alert when support is needed. Describes that the model has long bridging extrusions which may print badly
case SupportSpotsGenerator::SupportPointCause::LongBridge: message = L("Long bridging extrusions"); break; case SupportSpotsGenerator::SupportPointCause::LongBridge: message = _u8L("Long bridging extrusions"); break;
//TRN Alert when support is needed. Describes bridge anchors/turns in the air, which will definitely print badly //TRN Alert when support is needed. Describes bridge anchors/turns in the air, which will definitely print badly
case SupportSpotsGenerator::SupportPointCause::FloatingBridgeAnchor: message = L("Floating bridge anchors"); break; case SupportSpotsGenerator::SupportPointCause::FloatingBridgeAnchor: message = _u8L("Floating bridge anchors"); break;
case SupportSpotsGenerator::SupportPointCause::FloatingExtrusion: case SupportSpotsGenerator::SupportPointCause::FloatingExtrusion:
if (critical) { if (critical) {
//TRN Alert when support is needed. Describes that the print has large overhang area which will print badly or not print at all. //TRN Alert when support is needed. Describes that the print has large overhang area which will print badly or not print at all.
message = L("Collapsing overhang"); message = _u8L("Collapsing overhang");
} else { } else {
//TRN Alert when support is needed. Describes extrusions that are not supported enough and come out curled or loose. //TRN Alert when support is needed. Describes extrusions that are not supported enough and come out curled or loose.
message = L("Loose extrusions"); message = _u8L("Loose extrusions");
} }
break; break;
//TRN Alert when support is needed. Describes that the print has low bed adhesion and may became loose. //TRN Alert when support is needed. Describes that the print has low bed adhesion and may became loose.
case SupportSpotsGenerator::SupportPointCause::SeparationFromBed: message = L("Low bed adhesion"); break; case SupportSpotsGenerator::SupportPointCause::SeparationFromBed: message = _u8L("Low bed adhesion"); break;
//TRN Alert when support is needed. Describes that the object has part that is not connected to the bed and will not print at all without supports. //TRN Alert when support is needed. Describes that the object has part that is not connected to the bed and will not print at all without supports.
case SupportSpotsGenerator::SupportPointCause::UnstableFloatingPart: message = L("Floating object part"); break; case SupportSpotsGenerator::SupportPointCause::UnstableFloatingPart: message = _u8L("Floating object part"); break;
//TRN Alert when support is needed. Describes that the object has thin part that may brake during printing //TRN Alert when support is needed. Describes that the object has thin part that may brake during printing
case SupportSpotsGenerator::SupportPointCause::WeakObjectPart: message = L("Thin fragile part"); break; case SupportSpotsGenerator::SupportPointCause::WeakObjectPart: message = _u8L("Thin fragile part"); break;
} }
return message; return message;
@ -1299,13 +1310,13 @@ void Print::alert_when_supports_needed()
} }
lines.push_back(""); lines.push_back("");
lines.push_back(L("Consider enabling supports.")); lines.push_back(_u8L("Consider enabling supports."));
if (recommend_brim) { if (recommend_brim) {
lines.push_back(L("Also consider enabling brim.")); lines.push_back(_u8L("Also consider enabling brim."));
} }
// TRN Alert message for detected print issues. first argument is a list of detected issues. // TRN Alert message for detected print issues. first argument is a list of detected issues.
auto message = Slic3r::format(L("Detected print stability issues:\n%1%"), elements_to_translated_list(lines, multiline_list_rule)); auto message = Slic3r::format(_u8L("Detected print stability issues:\n%1%"), elements_to_translated_list(lines, multiline_list_rule));
if (objects_isssues.size() > 0) { if (objects_isssues.size() > 0) {
this->active_step_add_warning(PrintStateBase::WarningLevel::NON_CRITICAL, message); this->active_step_add_warning(PrintStateBase::WarningLevel::NON_CRITICAL, message);
@ -1447,6 +1458,7 @@ void Print::_make_wipe_tower()
wipe_tower.generate(m_wipe_tower_data.tool_changes); wipe_tower.generate(m_wipe_tower_data.tool_changes);
m_wipe_tower_data.depth = wipe_tower.get_depth(); m_wipe_tower_data.depth = wipe_tower.get_depth();
m_wipe_tower_data.brim_width = wipe_tower.get_brim_width(); m_wipe_tower_data.brim_width = wipe_tower.get_brim_width();
m_wipe_tower_data.height = wipe_tower.get_wipe_tower_height();
// Unload the current filament over the purge tower. // Unload the current filament over the purge tower.
coordf_t layer_height = m_objects.front()->config().layer_height.value; coordf_t layer_height = m_objects.front()->config().layer_height.value;

View File

@ -434,6 +434,7 @@ struct WipeTowerData
// Depth of the wipe tower to pass to GLCanvas3D for exact bounding box: // Depth of the wipe tower to pass to GLCanvas3D for exact bounding box:
float depth; float depth;
float brim_width; float brim_width;
float height;
void clear() { void clear() {
priming.reset(nullptr); priming.reset(nullptr);

View File

@ -6,10 +6,6 @@
#include "I18N.hpp" #include "I18N.hpp"
//! macro used to mark string used at localization,
//! return same string
#define L(s) Slic3r::I18N::translate(s)
namespace Slic3r namespace Slic3r
{ {
@ -81,7 +77,7 @@ std::string PrintBase::output_filename(const std::string &format, const std::str
filename = boost::filesystem::change_extension(filename, default_ext); filename = boost::filesystem::change_extension(filename, default_ext);
return filename.string(); return filename.string();
} catch (std::runtime_error &err) { } catch (std::runtime_error &err) {
throw Slic3r::PlaceholderParserError(L("Failed processing of the output_filename_format template.") + "\n" + err.what()); throw Slic3r::PlaceholderParserError(_u8L("Failed processing of the output_filename_format template.") + "\n" + err.what());
} }
} }

View File

@ -16,11 +16,6 @@
namespace Slic3r { namespace Slic3r {
//! macro used to mark string used at localization,
//! return same string
#define L(s) (s)
#define _(s) Slic3r::I18N::translate(s)
static t_config_enum_names enum_names_from_keys_map(const t_config_enum_values &enum_keys_map) static t_config_enum_names enum_names_from_keys_map(const t_config_enum_values &enum_keys_map)
{ {
t_config_enum_names names; t_config_enum_names names;
@ -404,6 +399,7 @@ void PrintConfigDef::init_fff_params()
const int max_temp = 1500; const int max_temp = 1500;
def = this->add("avoid_crossing_curled_overhangs", coBool); def = this->add("avoid_crossing_curled_overhangs", coBool);
def->label = L("Avoid crossing curled overhangs (Experimental)"); def->label = L("Avoid crossing curled overhangs (Experimental)");
// TRN PrintSettings: "Avoid crossing curled overhangs (Experimental)"
def->tooltip = L("Plan travel moves such that the extruder avoids areas where the filament may be curled up. " def->tooltip = L("Plan travel moves such that the extruder avoids areas where the filament may be curled up. "
"This is mostly happening on steeper rounded overhangs and may cause a crash with the nozzle. " "This is mostly happening on steeper rounded overhangs and may cause a crash with the nozzle. "
"This feature slows down both the print and the G-code generation."); "This feature slows down both the print and the G-code generation.");
@ -461,8 +457,8 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionString("")); def->set_default_value(new ConfigOptionString(""));
def = this->add("bottom_solid_layers", coInt); def = this->add("bottom_solid_layers", coInt);
//TRN To be shown in Print Settings "Bottom solid layers" //TRN Print Settings: "Bottom solid layers"
def->label = L("Bottom"); def->label = L_CONTEXT("Bottom", "Layers");
def->category = L("Layers and Perimeters"); def->category = L("Layers and Perimeters");
def->tooltip = L("Number of solid layers to generate on bottom surfaces."); def->tooltip = L("Number of solid layers to generate on bottom surfaces.");
def->full_label = L("Bottom solid layers"); def->full_label = L("Bottom solid layers");
@ -470,8 +466,7 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionInt(3)); def->set_default_value(new ConfigOptionInt(3));
def = this->add("bottom_solid_min_thickness", coFloat); def = this->add("bottom_solid_min_thickness", coFloat);
//TRN To be shown in Print Settings "Top solid layers" def->label = L_CONTEXT("Bottom", "Layers");
def->label = L("Bottom");
def->category = L("Layers and Perimeters"); def->category = L("Layers and Perimeters");
def->tooltip = L("The number of bottom solid layers is increased above bottom_solid_layers if necessary to satisfy " def->tooltip = L("The number of bottom solid layers is increased above bottom_solid_layers if necessary to satisfy "
"minimum thickness of bottom shell."); "minimum thickness of bottom shell.");
@ -538,6 +533,7 @@ void PrintConfigDef::init_fff_params()
def->mode = comExpert; def->mode = comExpert;
def->set_default_value(new ConfigOptionBool(false)); def->set_default_value(new ConfigOptionBool(false));
// TRN PrintSettings : "Dynamic overhang speed"
auto overhang_speed_setting_description = L("Overhang size is expressed as a percentage of overlap of the extrusion with the previous layer: " auto overhang_speed_setting_description = L("Overhang size is expressed as a percentage of overlap of the extrusion with the previous layer: "
"100% would be full overlap (no overhang), while 0% represents full overhang (floating extrusion, bridge). " "100% would be full overlap (no overhang), while 0% represents full overhang (floating extrusion, bridge). "
"Speeds for overhang sizes in between are calculated via linear interpolation. " "Speeds for overhang sizes in between are calculated via linear interpolation. "
@ -585,10 +581,11 @@ void PrintConfigDef::init_fff_params()
def->mode = comExpert; def->mode = comExpert;
def->set_default_value(new ConfigOptionBools{false}); def->set_default_value(new ConfigOptionBools{false});
// TRN FilamentSettings : "Dynamic fan speeds"
auto fan_speed_setting_description = L( auto fan_speed_setting_description = L(
"Overhang size is expressed as a percentage of overlap of the extrusion with the previous layer: " "Overhang size is expressed as a percentage of overlap of the extrusion with the previous layer: "
"100% would be full overlap (no overhang), while 0% represents full overhang (floating extrusion, bridge). " "100% would be full overlap (no overhang), while 0% represents full overhang (floating extrusion, bridge). "
"Fan speeds for overhang sizes in between are calculated via linear interpolation. "); "Fan speeds for overhang sizes in between are calculated via linear interpolation.");
def = this->add("overhang_fan_speed_0", coInts); def = this->add("overhang_fan_speed_0", coInts);
def->label = L("speed for 0% overlap (bridge)"); def->label = L("speed for 0% overlap (bridge)");
@ -1966,7 +1963,8 @@ void PrintConfigDef::init_fff_params()
def = this->add("ooze_prevention", coBool); def = this->add("ooze_prevention", coBool);
def->label = L("Enable"); def->label = L("Enable");
def->tooltip = L("This option will drop the temperature of the inactive extruders to prevent oozing. "); // TRN PrintSettings: Enable ooze prevention
def->tooltip = L("This option will drop the temperature of the inactive extruders to prevent oozing.");
def->mode = comExpert; def->mode = comExpert;
def->set_default_value(new ConfigOptionBool(false)); def->set_default_value(new ConfigOptionBool(false));
@ -2304,6 +2302,7 @@ void PrintConfigDef::init_fff_params()
def = this->add("staggered_inner_seams", coBool); def = this->add("staggered_inner_seams", coBool);
def->label = L("Staggered inner seams"); def->label = L("Staggered inner seams");
// TRN PrintSettings: "Staggered inner seams"
def->tooltip = L("This option causes the inner seams to be shifted backwards based on their depth, forming a zigzag pattern."); def->tooltip = L("This option causes the inner seams to be shifted backwards based on their depth, forming a zigzag pattern.");
def->mode = comAdvanced; def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBool(false)); def->set_default_value(new ConfigOptionBool(false));
@ -2469,6 +2468,7 @@ void PrintConfigDef::init_fff_params()
def = this->add("standby_temperature_delta", coInt); def = this->add("standby_temperature_delta", coInt);
def->label = L("Temperature variation"); def->label = L("Temperature variation");
// TRN PrintSettings : "Ooze prevention" > "Temperature variation"
def->tooltip = L("Temperature difference to be applied when an extruder is not active. " def->tooltip = L("Temperature difference to be applied when an extruder is not active. "
"The value is not used when 'idle_temperature' in filament settings " "The value is not used when 'idle_temperature' in filament settings "
"is defined."); "is defined.");
@ -2646,8 +2646,8 @@ void PrintConfigDef::init_fff_params()
"If set to zero, support_material_contact_distance will be used for both top and bottom contact Z distances."); "If set to zero, support_material_contact_distance will be used for both top and bottom contact Z distances.");
def->sidetext = L("mm"); def->sidetext = L("mm");
// def->min = 0; // def->min = 0;
//TRN To be shown in Print Settings "Bottom contact Z distance". Have to be as short as possible
def->set_enum_values(ConfigOptionDef::GUIType::f_enum_open, { def->set_enum_values(ConfigOptionDef::GUIType::f_enum_open, {
//TRN Print Settings: "Bottom contact Z distance". Have to be as short as possible
{ "0", L("Same as top") }, { "0", L("Same as top") },
{ "0.1", "0.1" }, { "0.1", "0.1" },
{ "0.2", "0.2" } { "0.2", "0.2" }
@ -2705,7 +2705,7 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced; def->mode = comAdvanced;
def->set_default_value(new ConfigOptionInt(1)); def->set_default_value(new ConfigOptionInt(1));
auto support_material_interface_layers = def = this->add("support_material_interface_layers", coInt); def = this->add("support_material_interface_layers", coInt);
def->label = L("Top interface layers"); def->label = L("Top interface layers");
def->category = L("Support material"); def->category = L("Support material");
def->tooltip = L("Number of interface layers to insert between the object(s) and support material."); def->tooltip = L("Number of interface layers to insert between the object(s) and support material.");
@ -2727,8 +2727,8 @@ void PrintConfigDef::init_fff_params()
"Set to -1 to use support_material_interface_layers"); "Set to -1 to use support_material_interface_layers");
def->sidetext = L("layers"); def->sidetext = L("layers");
def->min = -1; def->min = -1;
//TRN To be shown in Print Settings "Bottom interface layers". Have to be as short as possible
def->set_enum_values(ConfigOptionDef::GUIType::i_enum_open, { def->set_enum_values(ConfigOptionDef::GUIType::i_enum_open, {
//TRN Print Settings: "Bottom interface layers". Have to be as short as possible
{ "-1", L("Same as top") }, { "-1", L("Same as top") },
{ "0", L("0 (off)") }, { "0", L("0 (off)") },
{ "1", L("1 (light)") }, { "1", L("1 (light)") },
@ -2829,6 +2829,7 @@ void PrintConfigDef::init_fff_params()
def = this->add("support_material_synchronize_layers", coBool); def = this->add("support_material_synchronize_layers", coBool);
def->label = L("Synchronize with object layers"); def->label = L("Synchronize with object layers");
def->category = L("Support material"); def->category = L("Support material");
// TRN PrintSettings : "Synchronize with object layers"
def->tooltip = L("Synchronize support layers with the object print layers. This is useful " def->tooltip = L("Synchronize support layers with the object print layers. This is useful "
"with multi-material printers, where the extruder switch is expensive. " "with multi-material printers, where the extruder switch is expensive. "
"This option is only available when top contact Z distance is set to zero."); "This option is only available when top contact Z distance is set to zero.");
@ -2860,6 +2861,7 @@ void PrintConfigDef::init_fff_params()
def = this->add("support_tree_angle", coFloat); def = this->add("support_tree_angle", coFloat);
def->label = L("Maximum Branch Angle"); def->label = L("Maximum Branch Angle");
def->category = L("Support material"); def->category = L("Support material");
// TRN PrintSettings: "Organic supports" > "Maximum Branch Angle"
def->tooltip = L("The maximum angle of the branches, when the branches have to avoid the model. " def->tooltip = L("The maximum angle of the branches, when the branches have to avoid the model. "
"Use a lower angle to make them more vertical and more stable. Use a higher angle to be able to have more reach."); "Use a lower angle to make them more vertical and more stable. Use a higher angle to be able to have more reach.");
def->sidetext = L("°"); def->sidetext = L("°");
@ -2871,6 +2873,7 @@ void PrintConfigDef::init_fff_params()
def = this->add("support_tree_angle_slow", coFloat); def = this->add("support_tree_angle_slow", coFloat);
def->label = L("Preferred Branch Angle"); def->label = L("Preferred Branch Angle");
def->category = L("Support material"); def->category = L("Support material");
// TRN PrintSettings: "Organic supports" > "Preferred Branch Angle"
def->tooltip = L("The preferred angle of the branches, when they do not have to avoid the model. " def->tooltip = L("The preferred angle of the branches, when they do not have to avoid the model. "
"Use a lower angle to make them more vertical and more stable. Use a higher angle for branches to merge faster."); "Use a lower angle to make them more vertical and more stable. Use a higher angle for branches to merge faster.");
def->sidetext = L("°"); def->sidetext = L("°");
@ -2882,6 +2885,7 @@ void PrintConfigDef::init_fff_params()
def = this->add("support_tree_tip_diameter", coFloat); def = this->add("support_tree_tip_diameter", coFloat);
def->label = L("Tip Diameter"); def->label = L("Tip Diameter");
def->category = L("Support material"); def->category = L("Support material");
// TRN PrintSettings: "Organic supports" > "Tip Diameter"
def->tooltip = L("The diameter of the top of the tip of the branches of organic support."); def->tooltip = L("The diameter of the top of the tip of the branches of organic support.");
def->sidetext = L("mm"); def->sidetext = L("mm");
def->min = 0; def->min = 0;
@ -2891,6 +2895,7 @@ void PrintConfigDef::init_fff_params()
def = this->add("support_tree_branch_diameter", coFloat); def = this->add("support_tree_branch_diameter", coFloat);
def->label = L("Branch Diameter"); def->label = L("Branch Diameter");
def->category = L("Support material"); def->category = L("Support material");
// TRN PrintSettings: "Organic supports" > "Branch Diameter"
def->tooltip = L("The diameter of the thinnest branches of organic support. Thicker branches are more sturdy. " def->tooltip = L("The diameter of the thinnest branches of organic support. Thicker branches are more sturdy. "
"Branches towards the base will be thicker than this."); "Branches towards the base will be thicker than this.");
def->sidetext = L("mm"); def->sidetext = L("mm");
@ -2899,8 +2904,10 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionFloat(2)); def->set_default_value(new ConfigOptionFloat(2));
def = this->add("support_tree_branch_diameter_angle", coFloat); def = this->add("support_tree_branch_diameter_angle", coFloat);
// TRN PrintSettings: #lmFIXME
def->label = L("Branch Diameter Angle"); def->label = L("Branch Diameter Angle");
def->category = L("Support material"); def->category = L("Support material");
// TRN PrintSettings: "Organic supports" > "Branch Diameter Angle"
def->tooltip = L("The angle of the branches' diameter as they gradually become thicker towards the bottom. " def->tooltip = L("The angle of the branches' diameter as they gradually become thicker towards the bottom. "
"An angle of 0 will cause the branches to have uniform thickness over their length. " "An angle of 0 will cause the branches to have uniform thickness over their length. "
"A bit of an angle can increase stability of the organic support."); "A bit of an angle can increase stability of the organic support.");
@ -2914,8 +2921,10 @@ void PrintConfigDef::init_fff_params()
// How far apart the branches need to be when they touch the model. Making this distance small will cause // How far apart the branches need to be when they touch the model. Making this distance small will cause
// the tree support to touch the model at more points, causing better overhang but making support harder to remove. // the tree support to touch the model at more points, causing better overhang but making support harder to remove.
def = this->add("support_tree_branch_distance", coFloat); def = this->add("support_tree_branch_distance", coFloat);
// TRN PrintSettings: #lmFIXME
def->label = L("Branch Distance"); def->label = L("Branch Distance");
def->category = L("Support material"); def->category = L("Support material");
// TRN PrintSettings: "Organic supports" > "Branch Distance"
def->tooltip = L("How far apart the branches need to be when they touch the model. " def->tooltip = L("How far apart the branches need to be when they touch the model. "
"Making this distance small will cause the tree support to touch the model at more points, " "Making this distance small will cause the tree support to touch the model at more points, "
"causing better overhang but making support harder to remove."); "causing better overhang but making support harder to remove.");
@ -2925,6 +2934,7 @@ void PrintConfigDef::init_fff_params()
def = this->add("support_tree_top_rate", coPercent); def = this->add("support_tree_top_rate", coPercent);
def->label = L("Branch Density"); def->label = L("Branch Density");
def->category = L("Support material"); def->category = L("Support material");
// TRN PrintSettings: "Organic supports" > "Branch Density"
def->tooltip = L("Adjusts the density of the support structure used to generate the tips of the branches. " def->tooltip = L("Adjusts the density of the support structure used to generate the tips of the branches. "
"A higher value results in better overhangs but the supports are harder to remove, " "A higher value results in better overhangs but the supports are harder to remove, "
"thus it is recommended to enable top support interfaces instead of a high branch density value " "thus it is recommended to enable top support interfaces instead of a high branch density value "
@ -3013,8 +3023,8 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionFloatOrPercent(15, false)); def->set_default_value(new ConfigOptionFloatOrPercent(15, false));
def = this->add("top_solid_layers", coInt); def = this->add("top_solid_layers", coInt);
//TRN To be shown in Print Settings "Top solid layers" //TRN Print Settings: "Top solid layers"
def->label = L("Top"); def->label = L_CONTEXT("Top", "Layers");
def->category = L("Layers and Perimeters"); def->category = L("Layers and Perimeters");
def->tooltip = L("Number of solid layers to generate on top surfaces."); def->tooltip = L("Number of solid layers to generate on top surfaces.");
def->full_label = L("Top solid layers"); def->full_label = L("Top solid layers");
@ -3022,8 +3032,7 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionInt(3)); def->set_default_value(new ConfigOptionInt(3));
def = this->add("top_solid_min_thickness", coFloat); def = this->add("top_solid_min_thickness", coFloat);
//TRN To be shown in Print Settings "Top solid layers" def->label = L_CONTEXT("Top", "Layers");
def->label = L("Top");
def->category = L("Layers and Perimeters"); def->category = L("Layers and Perimeters");
def->tooltip = L("The number of top solid layers is increased above top_solid_layers if necessary to satisfy " def->tooltip = L("The number of top solid layers is increased above top_solid_layers if necessary to satisfy "
"minimum thickness of top shell." "minimum thickness of top shell."
@ -3150,6 +3159,25 @@ void PrintConfigDef::init_fff_params()
def->min = 0.; def->min = 0.;
def->set_default_value(new ConfigOptionFloat(2.)); def->set_default_value(new ConfigOptionFloat(2.));
def = this->add("wipe_tower_cone_angle", coFloat);
def->label = L("Stabilization cone apex angle");
def->tooltip = L("Angle at the apex of the cone that is used to stabilize the wipe tower. "
"Larger angle means wider base.");
def->sidetext = L("°");
def->mode = comAdvanced;
def->min = 0.;
def->max = 90.;
def->set_default_value(new ConfigOptionFloat(0.));
def = this->add("wipe_tower_extra_spacing", coPercent);
def->label = L("Wipe tower purge lines spacing");
def->tooltip = L("Spacing of purge lines on the wipe tower.");
def->sidetext = L("%");
def->mode = comExpert;
def->min = 100.;
def->max = 300.;
def->set_default_value(new ConfigOptionPercent(100.));
def = this->add("wipe_into_infill", coBool); def = this->add("wipe_into_infill", coBool);
def->category = L("Wipe options"); def->category = L("Wipe options");
def->label = L("Wipe into this object's infill"); def->label = L("Wipe into this object's infill");
@ -3860,7 +3888,9 @@ void PrintConfigDef::init_sla_params()
def->tooltip = L("Support tree building strategy"); def->tooltip = L("Support tree building strategy");
def->set_enum<sla::SupportTreeType>( def->set_enum<sla::SupportTreeType>(
ConfigOptionEnum<sla::SupportTreeType>::get_enum_names(), ConfigOptionEnum<sla::SupportTreeType>::get_enum_names(),
{ L("Default"), L("Branching (experimental)") }); { L("Default"),
// TRN One of the "Support tree type"s on SLAPrintSettings : Supports
L("Branching (experimental)") });
// TODO: def->enum_def->labels[2] = L("Organic"); // TODO: def->enum_def->labels[2] = L("Organic");
def->mode = comSimple; def->mode = comSimple;
def->set_default_value(new ConfigOptionEnum(sla::SupportTreeType::Default)); def->set_default_value(new ConfigOptionEnum(sla::SupportTreeType::Default));

View File

@ -823,6 +823,8 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionFloat, wipe_tower_per_color_wipe)) ((ConfigOptionFloat, wipe_tower_per_color_wipe))
((ConfigOptionFloat, wipe_tower_rotation_angle)) ((ConfigOptionFloat, wipe_tower_rotation_angle))
((ConfigOptionFloat, wipe_tower_brim_width)) ((ConfigOptionFloat, wipe_tower_brim_width))
((ConfigOptionFloat, wipe_tower_cone_angle))
((ConfigOptionPercent, wipe_tower_extra_spacing))
((ConfigOptionFloat, wipe_tower_bridging)) ((ConfigOptionFloat, wipe_tower_bridging))
((ConfigOptionFloats, wiping_volumes_matrix)) ((ConfigOptionFloats, wiping_volumes_matrix))
((ConfigOptionFloats, wiping_volumes_extruders)) ((ConfigOptionFloats, wiping_volumes_extruders))

View File

@ -56,10 +56,6 @@
using namespace std::literals; using namespace std::literals;
//! macro used to mark string used at localization,
//! return same string
#define L(s) Slic3r::I18N::translate(s)
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING #ifdef SLIC3R_DEBUG_SLICE_PROCESSING
#define SLIC3R_DEBUG #define SLIC3R_DEBUG
#endif #endif
@ -153,7 +149,7 @@ void PrintObject::make_perimeters()
if (! this->set_started(posPerimeters)) if (! this->set_started(posPerimeters))
return; return;
m_print->set_status(20, L("Generating perimeters")); m_print->set_status(20, _u8L("Generating perimeters"));
BOOST_LOG_TRIVIAL(info) << "Generating perimeters..." << log_memory_info(); BOOST_LOG_TRIVIAL(info) << "Generating perimeters..." << log_memory_info();
// Revert the typed slices into untyped slices. // Revert the typed slices into untyped slices.
@ -258,7 +254,7 @@ void PrintObject::prepare_infill()
if (! this->set_started(posPrepareInfill)) if (! this->set_started(posPrepareInfill))
return; return;
m_print->set_status(30, L("Preparing infill")); m_print->set_status(30, _u8L("Preparing infill"));
if (m_typed_slices) { if (m_typed_slices) {
// To improve robustness of detect_surfaces_type() when reslicing (working with typed slices), see GH issue #7442. // To improve robustness of detect_surfaces_type() when reslicing (working with typed slices), see GH issue #7442.
@ -403,7 +399,8 @@ void PrintObject::infill()
this->prepare_infill(); this->prepare_infill();
if (this->set_started(posInfill)) { if (this->set_started(posInfill)) {
m_print->set_status(45, L("making infill")); // TRN Status for the Print calculation
m_print->set_status(45, _u8L("Making infill"));
const auto& adaptive_fill_octree = this->m_adaptive_fill_octrees.first; const auto& adaptive_fill_octree = this->m_adaptive_fill_octrees.first;
const auto& support_fill_octree = this->m_adaptive_fill_octrees.second; const auto& support_fill_octree = this->m_adaptive_fill_octrees.second;
@ -450,7 +447,7 @@ void PrintObject::generate_support_spots()
{ {
if (this->set_started(posSupportSpotsSearch)) { if (this->set_started(posSupportSpotsSearch)) {
BOOST_LOG_TRIVIAL(debug) << "Searching support spots - start"; BOOST_LOG_TRIVIAL(debug) << "Searching support spots - start";
m_print->set_status(65, L("Searching support spots")); m_print->set_status(65, _u8L("Searching support spots"));
if (!this->shared_regions()->generated_support_points.has_value()) { if (!this->shared_regions()->generated_support_points.has_value()) {
PrintTryCancel cancel_func = m_print->make_try_cancel(); PrintTryCancel cancel_func = m_print->make_try_cancel();
SupportSpotsGenerator::Params params{this->print()->m_config.filament_type.values, SupportSpotsGenerator::Params params{this->print()->m_config.filament_type.values,
@ -475,7 +472,7 @@ void PrintObject::generate_support_material()
if (this->set_started(posSupportMaterial)) { if (this->set_started(posSupportMaterial)) {
this->clear_support_layers(); this->clear_support_layers();
if ((this->has_support() && m_layers.size() > 1) || (this->has_raft() && ! m_layers.empty())) { if ((this->has_support() && m_layers.size() > 1) || (this->has_raft() && ! m_layers.empty())) {
m_print->set_status(70, L("Generating support material")); m_print->set_status(70, _u8L("Generating support material"));
this->_generate_support_material(); this->_generate_support_material();
m_print->throw_if_canceled(); m_print->throw_if_canceled();
} else { } else {
@ -496,7 +493,7 @@ void PrintObject::estimate_curled_extrusions()
if (this->set_started(posEstimateCurledExtrusions)) { if (this->set_started(posEstimateCurledExtrusions)) {
if (this->print()->config().avoid_crossing_curled_overhangs) { if (this->print()->config().avoid_crossing_curled_overhangs) {
BOOST_LOG_TRIVIAL(debug) << "Estimating areas with curled extrusions - start"; BOOST_LOG_TRIVIAL(debug) << "Estimating areas with curled extrusions - start";
m_print->set_status(88, L("Estimating curled extrusions")); m_print->set_status(88, _u8L("Estimating curled extrusions"));
// Estimate curling of support material and add it to the malformaition lines of each layer // Estimate curling of support material and add it to the malformaition lines of each layer
float support_flow_width = support_material_flow(this, this->config().layer_height).width(); float support_flow_width = support_material_flow(this, this->config().layer_height).width();

View File

@ -10,8 +10,6 @@
#include <tbb/parallel_for.h> #include <tbb/parallel_for.h>
//! macro used to mark string used at localization, return same string
#define L(s) Slic3r::I18N::translate(s)
namespace Slic3r { namespace Slic3r {
@ -499,7 +497,7 @@ void PrintObject::slice()
{ {
if (! this->set_started(posSlice)) if (! this->set_started(posSlice))
return; return;
m_print->set_status(10, L("Processing triangulated mesh")); m_print->set_status(10, _u8L("Processing triangulated mesh"));
std::vector<coordf_t> layer_height_profile; std::vector<coordf_t> layer_height_profile;
this->update_layer_height_profile(*this->model_object(), m_slicing_params, layer_height_profile); this->update_layer_height_profile(*this->model_object(), m_slicing_params, layer_height_profile);
m_print->throw_if_canceled(); m_print->throw_if_canceled();
@ -733,9 +731,9 @@ void PrintObject::slice_volumes()
if (m_config.xy_size_compensation.value != 0.f) { if (m_config.xy_size_compensation.value != 0.f) {
this->active_step_add_warning( this->active_step_add_warning(
PrintStateBase::WarningLevel::CRITICAL, PrintStateBase::WarningLevel::CRITICAL,
L("An object has enabled XY Size compensation which will not be used because it is also multi-material painted.\nXY Size " _u8L("An object has enabled XY Size compensation which will not be used because it is also multi-material painted.\nXY Size "
"compensation cannot be combined with multi-material painting.") + "compensation cannot be combined with multi-material painting.") +
"\n" + (L("Object name")) + ": " + this->model_object()->name); "\n" + (_u8L("Object name")) + ": " + this->model_object()->name);
} }
BOOST_LOG_TRIVIAL(debug) << "Slicing volumes - MMU segmentation"; BOOST_LOG_TRIVIAL(debug) << "Slicing volumes - MMU segmentation";

View File

@ -23,10 +23,6 @@
#include <libslic3r/MTUtils.hpp> #include <libslic3r/MTUtils.hpp>
#include <libslic3r/I18N.hpp> #include <libslic3r/I18N.hpp>
//! macro used to mark string used at localization,
//! return same string
#define L(s) Slic3r::I18N::translate(s)
namespace Slic3r { namespace Slic3r {
namespace sla { namespace sla {
@ -83,12 +79,12 @@ InteriorPtr generate_interior(const VoxelGrid &vgrid,
auto narrowb = 1.f; // voxel units (voxel count) auto narrowb = 1.f; // voxel units (voxel count)
if (ctl.stopcondition()) return {}; if (ctl.stopcondition()) return {};
else ctl.statuscb(0, L("Hollowing")); else ctl.statuscb(0, _u8L("Hollowing"));
auto gridptr = dilate_grid(vgrid, out_range, in_range); auto gridptr = dilate_grid(vgrid, out_range, in_range);
if (ctl.stopcondition()) return {}; if (ctl.stopcondition()) return {};
else ctl.statuscb(30, L("Hollowing")); else ctl.statuscb(30, _u8L("Hollowing"));
double iso_surface = D; double iso_surface = D;
if (D > EPSILON) { if (D > EPSILON) {
@ -103,7 +99,7 @@ InteriorPtr generate_interior(const VoxelGrid &vgrid,
} }
if (ctl.stopcondition()) return {}; if (ctl.stopcondition()) return {};
else ctl.statuscb(70, L("Hollowing")); else ctl.statuscb(70, _u8L("Hollowing"));
double adaptivity = 0.; double adaptivity = 0.;
InteriorPtr interior = InteriorPtr{new Interior{}}; InteriorPtr interior = InteriorPtr{new Interior{}};
@ -112,7 +108,7 @@ InteriorPtr generate_interior(const VoxelGrid &vgrid,
interior->gridptr = std::move(gridptr); interior->gridptr = std::move(gridptr);
if (ctl.stopcondition()) return {}; if (ctl.stopcondition()) return {};
else ctl.statuscb(100, L("Hollowing")); else ctl.statuscb(100, _u8L("Hollowing"));
interior->iso_surface = iso_surface; interior->iso_surface = iso_surface;
interior->thickness = offset; interior->thickness = offset;

View File

@ -21,9 +21,6 @@
#include "I18N.hpp" #include "I18N.hpp"
#include <boost/log/trivial.hpp> #include <boost/log/trivial.hpp>
//! macro used to mark string used at localization,
//! return same string
#define L(s) Slic3r::I18N::translate(s)
namespace Slic3r { namespace sla { namespace Slic3r { namespace sla {
@ -530,7 +527,7 @@ std::string PadConfig::validate() const
if (brim_size_mm < MIN_BRIM_SIZE_MM || if (brim_size_mm < MIN_BRIM_SIZE_MM ||
bottom_offset() > brim_size_mm + wing_distance() || bottom_offset() > brim_size_mm + wing_distance() ||
get_waffle_offset(*this) <= MIN_BRIM_SIZE_MM) get_waffle_offset(*this) <= MIN_BRIM_SIZE_MM)
return L("Pad brim size is too small for the current configuration."); return _u8L("Pad brim size is too small for the current configuration.");
return ""; return "";
} }

View File

@ -16,13 +16,9 @@
#include <libslic3r/TriangleMeshSlicer.hpp> #include <libslic3r/TriangleMeshSlicer.hpp>
#include <boost/log/trivial.hpp> #include <boost/log/trivial.hpp>
#include <libslic3r/I18N.hpp>
#include <libnest2d/tools/benchmark.h> #include <libnest2d/tools/benchmark.h>
//! macro used to mark string used at localization,
//! return same string
#define L(s) Slic3r::I18N::translate(s)
namespace Slic3r { namespace sla { namespace Slic3r { namespace sla {

View File

@ -23,7 +23,7 @@
//! macro used to mark string used at localization, //! macro used to mark string used at localization,
//! return same string //! return same string
#define L(s) Slic3r::I18N::translate(s) #define _u8L(s) Slic3r::I18N::translate(s)
namespace Slic3r { namespace Slic3r {
@ -543,7 +543,7 @@ std::string SLAPrint::validate(std::string*) const
if(supports_en && if(supports_en &&
mo->sla_points_status == sla::PointsStatus::UserModified && mo->sla_points_status == sla::PointsStatus::UserModified &&
mo->sla_support_points.empty()) mo->sla_support_points.empty())
return L("Cannot proceed without support points! " return _u8L("Cannot proceed without support points! "
"Add support points or disable support generation."); "Add support points or disable support generation.");
sla::SupportTreeConfig cfg = make_support_cfg(po->config()); sla::SupportTreeConfig cfg = make_support_cfg(po->config());
@ -554,13 +554,13 @@ std::string SLAPrint::validate(std::string*) const
sla::PadConfig::EmbedObject &builtinpad = padcfg.embed_object; sla::PadConfig::EmbedObject &builtinpad = padcfg.embed_object;
if(supports_en && !builtinpad.enabled && elv < cfg.head_fullwidth()) if(supports_en && !builtinpad.enabled && elv < cfg.head_fullwidth())
return L( return _u8L(
"Elevation is too low for object. Use the \"Pad around " "Elevation is too low for object. Use the \"Pad around "
"object\" feature to print the object without elevation."); "object\" feature to print the object without elevation.");
if(supports_en && builtinpad.enabled && if(supports_en && builtinpad.enabled &&
cfg.pillar_base_safety_distance_mm < builtinpad.object_gap_mm) { cfg.pillar_base_safety_distance_mm < builtinpad.object_gap_mm) {
return L( return _u8L(
"The endings of the support pillars will be deployed on the " "The endings of the support pillars will be deployed on the "
"gap between the object and the pad. 'Support base safety " "gap between the object and the pad. 'Support base safety "
"distance' has to be greater than the 'Pad object gap' " "distance' has to be greater than the 'Pad object gap' "
@ -576,14 +576,14 @@ std::string SLAPrint::validate(std::string*) const
double expt_cur = m_material_config.exposure_time.getFloat(); double expt_cur = m_material_config.exposure_time.getFloat();
if (expt_cur < expt_min || expt_cur > expt_max) if (expt_cur < expt_min || expt_cur > expt_max)
return L("Exposition time is out of printer profile bounds."); return _u8L("Exposition time is out of printer profile bounds.");
double iexpt_max = m_printer_config.max_initial_exposure_time.getFloat(); double iexpt_max = m_printer_config.max_initial_exposure_time.getFloat();
double iexpt_min = m_printer_config.min_initial_exposure_time.getFloat(); double iexpt_min = m_printer_config.min_initial_exposure_time.getFloat();
double iexpt_cur = m_material_config.initial_exposure_time.getFloat(); double iexpt_cur = m_material_config.initial_exposure_time.getFloat();
if (iexpt_cur < iexpt_min || iexpt_cur > iexpt_max) if (iexpt_cur < iexpt_min || iexpt_cur > iexpt_max)
return L("Initial exposition time is out of printer profile bounds."); return _u8L("Initial exposition time is out of printer profile bounds.");
return ""; return "";
} }
@ -690,7 +690,7 @@ void SLAPrint::process()
} }
// If everything vent well // If everything vent well
m_report_status(*this, 100, L("Slicing done")); m_report_status(*this, 100, _u8L("Slicing done"));
#ifdef SLAPRINT_DO_BENCHMARK #ifdef SLAPRINT_DO_BENCHMARK
std::string csvbenchstr; std::string csvbenchstr;

View File

@ -32,9 +32,6 @@
#include <libnest2d/tools/benchmark.h> #include <libnest2d/tools/benchmark.h>
//! macro used to mark string used at localization,
//! return same string
#define L(s) Slic3r::I18N::translate(s)
namespace Slic3r { namespace Slic3r {
@ -54,14 +51,15 @@ const std::array<unsigned, slaposCount> OBJ_STEP_LEVELS = {
std::string OBJ_STEP_LABELS(size_t idx) std::string OBJ_STEP_LABELS(size_t idx)
{ {
switch (idx) { switch (idx) {
case slaposAssembly: return L("Assembling model from parts"); // TRN Status of the SLA print calculation
case slaposHollowing: return L("Hollowing model"); case slaposAssembly: return _u8L("Assembling model from parts");
case slaposDrillHoles: return L("Drilling holes into model."); case slaposHollowing: return _u8L("Hollowing model");
case slaposObjectSlice: return L("Slicing model"); case slaposDrillHoles: return _u8L("Drilling holes into model.");
case slaposSupportPoints: return L("Generating support points"); case slaposObjectSlice: return _u8L("Slicing model");
case slaposSupportTree: return L("Generating support tree"); case slaposSupportPoints: return _u8L("Generating support points");
case slaposPad: return L("Generating pad"); case slaposSupportTree: return _u8L("Generating support tree");
case slaposSliceSupports: return L("Slicing supports"); case slaposPad: return _u8L("Generating pad");
case slaposSliceSupports: return _u8L("Slicing supports");
default:; default:;
} }
assert(false); assert(false);
@ -76,8 +74,8 @@ const std::array<unsigned, slapsCount> PRINT_STEP_LEVELS = {
std::string PRINT_STEP_LABELS(size_t idx) std::string PRINT_STEP_LABELS(size_t idx)
{ {
switch (idx) { switch (idx) {
case slapsMergeSlicesAndEval: return L("Merging slices and calculating statistics"); case slapsMergeSlicesAndEval: return _u8L("Merging slices and calculating statistics");
case slapsRasterize: return L("Rasterizing layers"); case slapsRasterize: return _u8L("Rasterizing layers");
default:; default:;
} }
assert(false); return "Out of bounds!"; assert(false); return "Out of bounds!";
@ -252,14 +250,14 @@ void SLAPrint::Steps::generate_preview(SLAPrintObject &po, SLAPrintObjectStep st
if (ret & static_cast<int>(sla::HollowMeshResult::FaultyMesh)) { if (ret & static_cast<int>(sla::HollowMeshResult::FaultyMesh)) {
po.active_step_add_warning( po.active_step_add_warning(
PrintStateBase::WarningLevel::NON_CRITICAL, PrintStateBase::WarningLevel::NON_CRITICAL,
L("Mesh to be hollowed is not suitable for hollowing (does not " _u8L("Mesh to be hollowed is not suitable for hollowing (does not "
"bound a volume).")); "bound a volume)."));
} }
if (ret & static_cast<int>(sla::HollowMeshResult::FaultyHoles)) { if (ret & static_cast<int>(sla::HollowMeshResult::FaultyHoles)) {
po.active_step_add_warning( po.active_step_add_warning(
PrintStateBase::WarningLevel::NON_CRITICAL, PrintStateBase::WarningLevel::NON_CRITICAL,
L("Unable to drill the current configuration of holes into the " _u8L("Unable to drill the current configuration of holes into the "
"model.")); "model."));
} }
@ -267,7 +265,7 @@ void SLAPrint::Steps::generate_preview(SLAPrintObject &po, SLAPrintObjectStep st
if (ret & static_cast<int>(sla::HollowMeshResult::DrillingFailed)) { if (ret & static_cast<int>(sla::HollowMeshResult::DrillingFailed)) {
po.active_step_add_warning( po.active_step_add_warning(
PrintStateBase::WarningLevel::NON_CRITICAL, L( PrintStateBase::WarningLevel::NON_CRITICAL, _u8L(
"Drilling holes into the mesh failed. " "Drilling holes into the mesh failed. "
"This is usually caused by broken model. Try to fix it first.")); "This is usually caused by broken model. Try to fix it first."));
@ -276,7 +274,7 @@ void SLAPrint::Steps::generate_preview(SLAPrintObject &po, SLAPrintObjectStep st
if (hole_fail) { if (hole_fail) {
po.active_step_add_warning(PrintStateBase::WarningLevel::NON_CRITICAL, po.active_step_add_warning(PrintStateBase::WarningLevel::NON_CRITICAL,
L("Failed to drill some holes into the model")); _u8L("Failed to drill some holes into the model"));
handled = false; handled = false;
} }
@ -286,7 +284,7 @@ void SLAPrint::Steps::generate_preview(SLAPrintObject &po, SLAPrintObjectStep st
if (!handled) { // Last resort to voxelization. if (!handled) { // Last resort to voxelization.
po.active_step_add_warning(PrintStateBase::WarningLevel::NON_CRITICAL, po.active_step_add_warning(PrintStateBase::WarningLevel::NON_CRITICAL,
L("Can't perform full mesh booleans! " _u8L("Can't perform full mesh booleans! "
"Some parts of the print will be previewed with approximated meshes. " "Some parts of the print will be previewed with approximated meshes. "
"This does not affect the quality of slices or the physical print in any way.")); "This does not affect the quality of slices or the physical print in any way."));
m = generate_preview_vdb(po, step); m = generate_preview_vdb(po, step);
@ -507,7 +505,7 @@ void SLAPrint::Steps::slice_model(SLAPrintObject &po)
if(slindex_it == po.m_slice_index.end()) if(slindex_it == po.m_slice_index.end())
//TRN To be shown at the status bar on SLA slicing error. //TRN To be shown at the status bar on SLA slicing error.
throw Slic3r::RuntimeError( throw Slic3r::RuntimeError(
L("Slicing had to be stopped due to an internal error: " _u8L("Slicing had to be stopped due to an internal error: "
"Inconsistent slice index.")); "Inconsistent slice index."));
po.m_model_height_levels.clear(); po.m_model_height_levels.clear();
@ -688,7 +686,7 @@ void SLAPrint::Steps::support_points(SLAPrintObject &po)
// Using RELOAD_SLA_SUPPORT_POINTS to tell the Plater to pass // Using RELOAD_SLA_SUPPORT_POINTS to tell the Plater to pass
// the update status to GLGizmoSlaSupports // the update status to GLGizmoSlaSupports
report_status(-1, L("Generating support points"), report_status(-1, _u8L("Generating support points"),
SlicingStatus::RELOAD_SLA_SUPPORT_POINTS); SlicingStatus::RELOAD_SLA_SUPPORT_POINTS);
} else { } else {
// There are either some points on the front-end, or the user // There are either some points on the front-end, or the user
@ -737,7 +735,7 @@ void SLAPrint::Steps::support_tree(SLAPrintObject &po)
auto rc = SlicingStatus::RELOAD_SCENE; auto rc = SlicingStatus::RELOAD_SCENE;
// This is to prevent "Done." being displayed during merged_mesh() // This is to prevent "Done." being displayed during merged_mesh()
report_status(-1, L("Visualizing supports")); report_status(-1, _u8L("Visualizing supports"));
BOOST_LOG_TRIVIAL(debug) << "Processed support point count " BOOST_LOG_TRIVIAL(debug) << "Processed support point count "
<< po.m_supportdata->input.pts.size(); << po.m_supportdata->input.pts.size();
@ -746,7 +744,7 @@ void SLAPrint::Steps::support_tree(SLAPrintObject &po)
if(po.support_mesh().empty()) if(po.support_mesh().empty())
BOOST_LOG_TRIVIAL(warning) << "Support mesh is empty"; BOOST_LOG_TRIVIAL(warning) << "Support mesh is empty";
report_status(-1, L("Visualizing supports"), rc); report_status(-1, _u8L("Visualizing supports"), rc);
} }
void SLAPrint::Steps::generate_pad(SLAPrintObject &po) { void SLAPrint::Steps::generate_pad(SLAPrintObject &po) {
@ -776,7 +774,7 @@ void SLAPrint::Steps::generate_pad(SLAPrintObject &po) {
if (!validate_pad(po.m_supportdata->pad_mesh.its, pcfg)) if (!validate_pad(po.m_supportdata->pad_mesh.its, pcfg))
throw Slic3r::SlicingError( throw Slic3r::SlicingError(
L("No pad can be generated for this model with the " _u8L("No pad can be generated for this model with the "
"current configuration")); "current configuration"));
} else if(po.m_supportdata) { } else if(po.m_supportdata) {
@ -784,7 +782,7 @@ void SLAPrint::Steps::generate_pad(SLAPrintObject &po) {
} }
throw_if_canceled(); throw_if_canceled();
report_status(-1, L("Visualizing supports"), SlicingStatus::RELOAD_SCENE); report_status(-1, _u8L("Visualizing supports"), SlicingStatus::RELOAD_SCENE);
} }
// Slicing the support geometries similarly to the model slicing procedure. // Slicing the support geometries similarly to the model slicing procedure.
@ -905,7 +903,7 @@ void SLAPrint::Steps::initialize_printer_input()
for(const SliceRecord& slicerecord : o->get_slice_index()) { for(const SliceRecord& slicerecord : o->get_slice_index()) {
if (!slicerecord.is_valid()) if (!slicerecord.is_valid())
throw Slic3r::SlicingError( throw Slic3r::SlicingError(
L("There are unprintable objects. Try to " _u8L("There are unprintable objects. Try to "
"adjust support settings to make the " "adjust support settings to make the "
"objects printable.")); "objects printable."));

View File

@ -6,10 +6,6 @@
#include <boost/log/trivial.hpp> #include <boost/log/trivial.hpp>
#include "I18N.hpp" #include "I18N.hpp"
//! macro used to mark string used at localization,
//! return same string
#define L(s) Slic3r::I18N::translate(s)
#if defined(_MSC_VER) && _MSC_VER <= 1800 || __cplusplus < 201103L #if defined(_MSC_VER) && _MSC_VER <= 1800 || __cplusplus < 201103L
#define SLIC3R_NORETURN #define SLIC3R_NORETURN
#elif __cplusplus >= 201103L #elif __cplusplus >= 201103L
@ -24,7 +20,7 @@ public:
std::string formatted_errorstr() const std::string formatted_errorstr() const
{ {
return L("Error with zip archive") + " " + m_zipname + ": " + return _u8L("Error with zip archive") + " " + m_zipname + ": " +
get_errorstr(); get_errorstr();
} }

View File

@ -6,11 +6,7 @@
#include "boost/nowide/cstdio.hpp" #include "boost/nowide/cstdio.hpp"
#endif #endif
#include "I18N.hpp" #include "libslic3r/I18N.hpp"
//! macro used to mark string used at localization,
//! return same string
#define L(s) Slic3r::I18N::translate(s)
namespace Slic3r { namespace Slic3r {
@ -88,67 +84,67 @@ std::string MZ_Archive::get_errorstr(mz_zip_error mz_err)
case MZ_ZIP_NO_ERROR: case MZ_ZIP_NO_ERROR:
return "no error"; return "no error";
case MZ_ZIP_UNDEFINED_ERROR: case MZ_ZIP_UNDEFINED_ERROR:
return L("undefined error"); return _u8L("undefined error");
case MZ_ZIP_TOO_MANY_FILES: case MZ_ZIP_TOO_MANY_FILES:
return L("too many files"); return _u8L("too many files");
case MZ_ZIP_FILE_TOO_LARGE: case MZ_ZIP_FILE_TOO_LARGE:
return L("file too large"); return _u8L("file too large");
case MZ_ZIP_UNSUPPORTED_METHOD: case MZ_ZIP_UNSUPPORTED_METHOD:
return L("unsupported method"); return _u8L("unsupported method");
case MZ_ZIP_UNSUPPORTED_ENCRYPTION: case MZ_ZIP_UNSUPPORTED_ENCRYPTION:
return L("unsupported encryption"); return _u8L("unsupported encryption");
case MZ_ZIP_UNSUPPORTED_FEATURE: case MZ_ZIP_UNSUPPORTED_FEATURE:
return L("unsupported feature"); return _u8L("unsupported feature");
case MZ_ZIP_FAILED_FINDING_CENTRAL_DIR: case MZ_ZIP_FAILED_FINDING_CENTRAL_DIR:
return L("failed finding central directory"); return _u8L("failed finding central directory");
case MZ_ZIP_NOT_AN_ARCHIVE: case MZ_ZIP_NOT_AN_ARCHIVE:
return L("not a ZIP archive"); return _u8L("not a ZIP archive");
case MZ_ZIP_INVALID_HEADER_OR_CORRUPTED: case MZ_ZIP_INVALID_HEADER_OR_CORRUPTED:
return L("invalid header or archive is corrupted"); return _u8L("invalid header or archive is corrupted");
case MZ_ZIP_UNSUPPORTED_MULTIDISK: case MZ_ZIP_UNSUPPORTED_MULTIDISK:
return L("unsupported multidisk archive"); return _u8L("unsupported multidisk archive");
case MZ_ZIP_DECOMPRESSION_FAILED: case MZ_ZIP_DECOMPRESSION_FAILED:
return L("decompression failed or archive is corrupted"); return _u8L("decompression failed or archive is corrupted");
case MZ_ZIP_COMPRESSION_FAILED: case MZ_ZIP_COMPRESSION_FAILED:
return L("compression failed"); return _u8L("compression failed");
case MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE: case MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE:
return L("unexpected decompressed size"); return _u8L("unexpected decompressed size");
case MZ_ZIP_CRC_CHECK_FAILED: case MZ_ZIP_CRC_CHECK_FAILED:
return L("CRC-32 check failed"); return _u8L("CRC-32 check failed");
case MZ_ZIP_UNSUPPORTED_CDIR_SIZE: case MZ_ZIP_UNSUPPORTED_CDIR_SIZE:
return L("unsupported central directory size"); return _u8L("unsupported central directory size");
case MZ_ZIP_ALLOC_FAILED: case MZ_ZIP_ALLOC_FAILED:
return L("allocation failed"); return _u8L("allocation failed");
case MZ_ZIP_FILE_OPEN_FAILED: case MZ_ZIP_FILE_OPEN_FAILED:
return L("file open failed"); return _u8L("file open failed");
case MZ_ZIP_FILE_CREATE_FAILED: case MZ_ZIP_FILE_CREATE_FAILED:
return L("file create failed"); return _u8L("file create failed");
case MZ_ZIP_FILE_WRITE_FAILED: case MZ_ZIP_FILE_WRITE_FAILED:
return L("file write failed"); return _u8L("file write failed");
case MZ_ZIP_FILE_READ_FAILED: case MZ_ZIP_FILE_READ_FAILED:
return L("file read failed"); return _u8L("file read failed");
case MZ_ZIP_FILE_CLOSE_FAILED: case MZ_ZIP_FILE_CLOSE_FAILED:
return L("file close failed"); return _u8L("file close failed");
case MZ_ZIP_FILE_SEEK_FAILED: case MZ_ZIP_FILE_SEEK_FAILED:
return L("file seek failed"); return _u8L("file seek failed");
case MZ_ZIP_FILE_STAT_FAILED: case MZ_ZIP_FILE_STAT_FAILED:
return L("file stat failed"); return _u8L("file stat failed");
case MZ_ZIP_INVALID_PARAMETER: case MZ_ZIP_INVALID_PARAMETER:
return L("invalid parameter"); return _u8L("invalid parameter");
case MZ_ZIP_INVALID_FILENAME: case MZ_ZIP_INVALID_FILENAME:
return L("invalid filename"); return _u8L("invalid filename");
case MZ_ZIP_BUF_TOO_SMALL: case MZ_ZIP_BUF_TOO_SMALL:
return L("buffer too small"); return _u8L("buffer too small");
case MZ_ZIP_INTERNAL_ERROR: case MZ_ZIP_INTERNAL_ERROR:
return L("internal error"); return _u8L("internal error");
case MZ_ZIP_FILE_NOT_FOUND: case MZ_ZIP_FILE_NOT_FOUND:
return L("file not found"); return _u8L("file not found");
case MZ_ZIP_ARCHIVE_TOO_LARGE: case MZ_ZIP_ARCHIVE_TOO_LARGE:
return L("archive is too large"); return _u8L("archive is too large");
case MZ_ZIP_VALIDATION_FAILED: case MZ_ZIP_VALIDATION_FAILED:
return L("validation failed"); return _u8L("validation failed");
case MZ_ZIP_WRITE_CALLBACK_FAILED: case MZ_ZIP_WRITE_CALLBACK_FAILED:
return L("write calledback failed"); return _u8L("write calledback failed");
default: default:
break; break;
} }

View File

@ -344,3 +344,6 @@ if (UNIX AND NOT APPLE)
target_include_directories(libslic3r_gui PRIVATE ${GTK${SLIC3R_GTK}_INCLUDE_DIRS}) target_include_directories(libslic3r_gui PRIVATE ${GTK${SLIC3R_GTK}_INCLUDE_DIRS})
target_link_libraries(libslic3r_gui ${GTK${SLIC3R_GTK}_LIBRARIES} fontconfig) target_link_libraries(libslic3r_gui ${GTK${SLIC3R_GTK}_LIBRARIES} fontconfig)
endif () endif ()
# Add a definition so that we can tell we are compiling slic3r.
target_compile_definitions(libslic3r_gui PRIVATE SLIC3R_CURRENTLY_COMPILING_GUI_MODULE)

View File

@ -480,11 +480,11 @@ int GLVolumeCollection::load_object_volume(
#if ENABLE_OPENGL_ES #if ENABLE_OPENGL_ES
int GLVolumeCollection::load_wipe_tower_preview( int GLVolumeCollection::load_wipe_tower_preview(
float pos_x, float pos_y, float width, float depth, float height, float pos_x, float pos_y, float width, float depth, float height, float cone_angle,
float rotation_angle, bool size_unknown, float brim_width, TriangleMesh* out_mesh) float rotation_angle, bool size_unknown, float brim_width, TriangleMesh* out_mesh)
#else #else
int GLVolumeCollection::load_wipe_tower_preview( int GLVolumeCollection::load_wipe_tower_preview(
float pos_x, float pos_y, float width, float depth, float height, float pos_x, float pos_y, float width, float depth, float height, float cone_angle,
float rotation_angle, bool size_unknown, float brim_width) float rotation_angle, bool size_unknown, float brim_width)
#endif // ENABLE_OPENGL_ES #endif // ENABLE_OPENGL_ES
{ {
@ -544,6 +544,21 @@ int GLVolumeCollection::load_wipe_tower_preview(
brim_mesh.translate(-brim_width, -brim_width, 0.f); brim_mesh.translate(-brim_width, -brim_width, 0.f);
mesh.merge(brim_mesh); mesh.merge(brim_mesh);
// Now the stabilization cone and its base.
const auto [R, scale_x] = WipeTower::get_wipe_tower_cone_base(width, height, depth, cone_angle);
if (R > 0.) {
TriangleMesh cone_mesh(its_make_cone(R, height));
cone_mesh.scale(Vec3f(1.f/scale_x, 1.f, 1.f));
TriangleMesh disk_mesh(its_make_cylinder(R, brim_height));
disk_mesh.scale(Vec3f(1. / scale_x, 1., 1.)); // Now it matches the base, which may be elliptic.
disk_mesh.scale(Vec3f(1.f + scale_x*brim_width/R, 1.f + brim_width/R, 1.f)); // Scale so the brim is not deformed.
cone_mesh.merge(disk_mesh);
cone_mesh.translate(width / 2., depth / 2., 0.);
mesh.merge(cone_mesh);
}
volumes.emplace_back(new GLVolume(color)); volumes.emplace_back(new GLVolume(color));
GLVolume& v = *volumes.back(); GLVolume& v = *volumes.back();
#if ENABLE_OPENGL_ES #if ENABLE_OPENGL_ES

View File

@ -424,10 +424,10 @@ public:
#if ENABLE_OPENGL_ES #if ENABLE_OPENGL_ES
int load_wipe_tower_preview( int load_wipe_tower_preview(
float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width, TriangleMesh* out_mesh = nullptr); float pos_x, float pos_y, float width, float depth, float height, float cone_angle, float rotation_angle, bool size_unknown, float brim_width, TriangleMesh* out_mesh = nullptr);
#else #else
int load_wipe_tower_preview( int load_wipe_tower_preview(
float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width); float pos_x, float pos_y, float width, float depth, float height, float cone_angle, float rotation_angle, bool size_unknown, float brim_width);
#endif // ENABLE_OPENGL_ES #endif // ENABLE_OPENGL_ES
// Load SLA auxiliary GLVolumes (for support trees or pad). // Load SLA auxiliary GLVolumes (for support trees or pad).

View File

@ -41,9 +41,9 @@ void AboutDialogLogo::onRepaint(wxEvent &event)
// CopyrightsDialog // CopyrightsDialog
// ----------------------------------------- // -----------------------------------------
CopyrightsDialog::CopyrightsDialog() CopyrightsDialog::CopyrightsDialog()
: DPIDialog(static_cast<wxWindow*>(wxGetApp().mainframe), wxID_ANY, from_u8((boost::format("%1% - %2%") : DPIDialog(static_cast<wxWindow*>(wxGetApp().mainframe), wxID_ANY, format_wxstr("%1% - %2%"
% (wxGetApp().is_editor() ? SLIC3R_APP_NAME : GCODEVIEWER_APP_NAME) , wxGetApp().is_editor() ? SLIC3R_APP_NAME : GCODEVIEWER_APP_NAME
% _utf8(L("Portions copyright"))).str()), , _L("Portions copyright")),
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{ {
this->SetFont(wxGetApp().normal_font()); this->SetFont(wxGetApp().normal_font());
@ -141,7 +141,6 @@ wxString CopyrightsDialog::get_html_text()
const auto bgr_clr_str = encode_color(ColorRGB(bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue())); const auto bgr_clr_str = encode_color(ColorRGB(bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue()));
const wxString copyright_str = _L("Copyright") + "&copy; "; const wxString copyright_str = _L("Copyright") + "&copy; ";
// TRN "Slic3r _is licensed under the_ License"
const wxString header_str = _L("License agreements of all following programs (libraries) are part of application license agreement"); const wxString header_str = _L("License agreements of all following programs (libraries) are part of application license agreement");
wxString text = wxString::Format( wxString text = wxString::Format(
@ -211,7 +210,7 @@ void CopyrightsDialog::onCloseDialog(wxEvent &)
} }
AboutDialog::AboutDialog() AboutDialog::AboutDialog()
: DPIDialog(static_cast<wxWindow*>(wxGetApp().mainframe), wxID_ANY, from_u8((boost::format(_utf8(L("About %s"))) % (wxGetApp().is_editor() ? SLIC3R_APP_NAME : GCODEVIEWER_APP_NAME)).str()), wxDefaultPosition, : DPIDialog(static_cast<wxWindow*>(wxGetApp().mainframe), wxID_ANY, format_wxstr(_L("About %s"), wxGetApp().is_editor() ? SLIC3R_APP_NAME : GCODEVIEWER_APP_NAME), wxDefaultPosition,
wxDefaultSize, /*wxCAPTION*/wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) wxDefaultSize, /*wxCAPTION*/wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{ {
SetFont(wxGetApp().normal_font()); SetFont(wxGetApp().normal_font());
@ -267,14 +266,13 @@ AboutDialog::AboutDialog()
int size[] = {fs,fs,fs,fs,fs,fs,fs}; int size[] = {fs,fs,fs,fs,fs,fs,fs};
m_html->SetFonts(font.GetFaceName(), font.GetFaceName(), size); m_html->SetFonts(font.GetFaceName(), font.GetFaceName(), size);
m_html->SetBorders(2); m_html->SetBorders(2);
const std::string copyright_str = _utf8(L("Copyright")); const wxString copyright_str = _L("Copyright");
// TRN "Slic3r _is licensed under the_ License" // TRN AboutDialog: "Slic3r %1% GNU Affero General Public License"
const std::string is_lecensed_str = _utf8(L("is licensed under the")); const wxString is_lecensed_str = _L("is licensed under the");
const std::string license_str = _utf8(L("GNU Affero General Public License, version 3")); const wxString license_str = _L("GNU Affero General Public License, version 3");
const std::string based_on_str = _utf8(L("PrusaSlicer is based on Slic3r by Alessandro Ranellucci and the RepRap community.")); const wxString based_on_str = _L("PrusaSlicer is based on Slic3r by Alessandro Ranellucci and the RepRap community.");
const std::string contributors_str = _utf8(L("Contributions by Henrik Brix Andersen, Nicolas Dandrimont, Mark Hindess, Petr Ledvina, Joseph Lenox, Y. Sapir, Mike Sheldrake, Vojtech Bubnik and numerous others.")); const wxString contributors_str = _L("Contributions by Henrik Brix Andersen, Nicolas Dandrimont, Mark Hindess, Petr Ledvina, Joseph Lenox, Y. Sapir, Mike Sheldrake, Vojtech Bubnik and numerous others.");
const auto text = from_u8( const auto text = format_wxstr(
(boost::format(
"<html>" "<html>"
"<body bgcolor= %1% link= %2%>" "<body bgcolor= %1% link= %2%>"
"<font color=%3%>" "<font color=%3%>"
@ -288,12 +286,12 @@ AboutDialog::AboutDialog()
"%9%" "%9%"
"</font>" "</font>"
"</body>" "</body>"
"</html>") % bgr_clr_str % text_clr_str % text_clr_str "</html>", bgr_clr_str, text_clr_str, text_clr_str
% copyright_str % copyright_str , copyright_str, copyright_str
% is_lecensed_str , is_lecensed_str
% license_str , license_str
% based_on_str , based_on_str
% contributors_str).str()); , contributors_str);
m_html->SetPage(text); m_html->SetPage(text);
vsizer->Add(m_html, 1, wxEXPAND | wxBOTTOM, 10); vsizer->Add(m_html, 1, wxEXPAND | wxBOTTOM, 10);
m_html->Bind(wxEVT_HTML_LINK_CLICKED, &AboutDialog::onLinkClicked, this); m_html->Bind(wxEVT_HTML_LINK_CLICKED, &AboutDialog::onLinkClicked, this);

View File

@ -76,10 +76,10 @@ std::pair<std::string, bool> SlicingProcessCompletedEvent::format_error_message(
try { try {
this->rethrow_exception(); this->rethrow_exception();
} catch (const std::bad_alloc &ex) { } catch (const std::bad_alloc &ex) {
wxString errmsg = GUI::from_u8((boost::format(_utf8(L("%s has encountered an error. It was likely caused by running out of memory. " error = GUI::format(_L("%s has encountered an error. It was likely caused by running out of memory. "
"If you are sure you have enough RAM on your system, this may also be a bug and we would " "If you are sure you have enough RAM on your system, this may also be a bug and we would "
"be glad if you reported it."))) % SLIC3R_APP_NAME).str()); "be glad if you reported it."), SLIC3R_APP_NAME);
error = std::string(errmsg.ToUTF8()) + "\n\n" + std::string(ex.what()); error += "\n\n" + std::string(ex.what());
} catch (const HardCrash &ex) { } catch (const HardCrash &ex) {
error = GUI::format(_L("PrusaSlicer has encountered a fatal error: \"%1%\""), ex.what()) + "\n\n" + error = GUI::format(_L("PrusaSlicer has encountered a fatal error: \"%1%\""), ex.what()) + "\n\n" +
_u8L("Please save your project and restart PrusaSlicer. " _u8L("Please save your project and restart PrusaSlicer. "
@ -159,7 +159,7 @@ void BackgroundSlicingProcess::process_fff()
wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, new wxCommandEvent(m_event_export_began_id)); wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, new wxCommandEvent(m_event_export_began_id));
prepare_upload(); prepare_upload();
} else { } else {
m_print->set_status(100, _utf8(L("Slicing complete"))); m_print->set_status(100, _u8L("Slicing complete"));
} }
this->set_step_done(bspsGCodeFinalize); this->set_step_done(bspsGCodeFinalize);
} }
@ -180,12 +180,12 @@ void BackgroundSlicingProcess::process_sla()
m_sla_print->export_print(export_path, thumbnails); m_sla_print->export_print(export_path, thumbnails);
m_print->set_status(100, (boost::format(_utf8(L("Masked SLA file exported to %1%"))) % export_path).str()); m_print->set_status(100, GUI::format(_L("Masked SLA file exported to %1%"), export_path));
} else if (! m_upload_job.empty()) { } else if (! m_upload_job.empty()) {
wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, new wxCommandEvent(m_event_export_began_id)); wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, new wxCommandEvent(m_event_export_began_id));
prepare_upload(); prepare_upload();
} else { } else {
m_print->set_status(100, _utf8(L("Slicing complete"))); m_print->set_status(100, _u8L("Slicing complete"));
} }
this->set_step_done(bspsGCodeFinalize); this->set_step_done(bspsGCodeFinalize);
} }
@ -649,7 +649,7 @@ bool BackgroundSlicingProcess::invalidate_all_steps()
// Copy the final G-code to target location (possibly a SD card, if it is a removable media, then verify that the file was written without an error). // Copy the final G-code to target location (possibly a SD card, if it is a removable media, then verify that the file was written without an error).
void BackgroundSlicingProcess::finalize_gcode() void BackgroundSlicingProcess::finalize_gcode()
{ {
m_print->set_status(95, _utf8(L("Running post-processing scripts"))); m_print->set_status(95, _u8L("Running post-processing scripts"));
// Perform the final post-processing of the export path by applying the print statistics over the file name. // Perform the final post-processing of the export path by applying the print statistics over the file name.
std::string export_path = m_fff_print->print_statistics().finalize_output_path(m_export_path); std::string export_path = m_fff_print->print_statistics().finalize_output_path(m_export_path);
@ -680,32 +680,32 @@ void BackgroundSlicingProcess::finalize_gcode()
catch (...) catch (...)
{ {
remove_post_processed_temp_file(); remove_post_processed_temp_file();
throw Slic3r::ExportError(_utf8(L("Unknown error occured during exporting G-code."))); throw Slic3r::ExportError(_u8L("Unknown error occured during exporting G-code."));
} }
switch (copy_ret_val) { switch (copy_ret_val) {
case CopyFileResult::SUCCESS: break; // no error case CopyFileResult::SUCCESS: break; // no error
case CopyFileResult::FAIL_COPY_FILE: case CopyFileResult::FAIL_COPY_FILE:
throw Slic3r::ExportError((boost::format(_utf8(L("Copying of the temporary G-code to the output G-code failed. Maybe the SD card is write locked?\nError message: %1%"))) % error_message).str()); throw Slic3r::ExportError(GUI::format(_L("Copying of the temporary G-code to the output G-code failed. Maybe the SD card is write locked?\nError message: %1%"), error_message));
break; break;
case CopyFileResult::FAIL_FILES_DIFFERENT: case CopyFileResult::FAIL_FILES_DIFFERENT:
throw Slic3r::ExportError((boost::format(_utf8(L("Copying of the temporary G-code to the output G-code failed. There might be problem with target device, please try exporting again or using different device. The corrupted output G-code is at %1%.tmp."))) % export_path).str()); throw Slic3r::ExportError(GUI::format(_L("Copying of the temporary G-code to the output G-code failed. There might be problem with target device, please try exporting again or using different device. The corrupted output G-code is at %1%.tmp."), export_path));
break; break;
case CopyFileResult::FAIL_RENAMING: case CopyFileResult::FAIL_RENAMING:
throw Slic3r::ExportError((boost::format(_utf8(L("Renaming of the G-code after copying to the selected destination folder has failed. Current path is %1%.tmp. Please try exporting again."))) % export_path).str()); throw Slic3r::ExportError(GUI::format(_L("Renaming of the G-code after copying to the selected destination folder has failed. Current path is %1%.tmp. Please try exporting again."), export_path));
break; break;
case CopyFileResult::FAIL_CHECK_ORIGIN_NOT_OPENED: case CopyFileResult::FAIL_CHECK_ORIGIN_NOT_OPENED:
throw Slic3r::ExportError((boost::format(_utf8(L("Copying of the temporary G-code has finished but the original code at %1% couldn't be opened during copy check. The output G-code is at %2%.tmp."))) % output_path % export_path).str()); throw Slic3r::ExportError(GUI::format(_L("Copying of the temporary G-code has finished but the original code at %1% couldn't be opened during copy check. The output G-code is at %2%.tmp."), output_path, export_path));
break; break;
case CopyFileResult::FAIL_CHECK_TARGET_NOT_OPENED: case CopyFileResult::FAIL_CHECK_TARGET_NOT_OPENED:
throw Slic3r::ExportError((boost::format(_utf8(L("Copying of the temporary G-code has finished but the exported code couldn't be opened during copy check. The output G-code is at %1%.tmp."))) % export_path).str()); throw Slic3r::ExportError(GUI::format(_L("Copying of the temporary G-code has finished but the exported code couldn't be opened during copy check. The output G-code is at %1%.tmp."), export_path));
break; break;
default: default:
throw Slic3r::ExportError(_utf8(L("Unknown error occured during exporting G-code."))); throw Slic3r::ExportError(_u8L("Unknown error occured during exporting G-code."));
BOOST_LOG_TRIVIAL(error) << "Unexpected fail code(" << (int)copy_ret_val << ") durring copy_file() to " << export_path << "."; BOOST_LOG_TRIVIAL(error) << "Unexpected fail code(" << (int)copy_ret_val << ") durring copy_file() to " << export_path << ".";
break; break;
} }
m_print->set_status(100, (boost::format(_utf8(L("G-code file exported to %1%"))) % export_path).str()); m_print->set_status(100, GUI::format(_L("G-code file exported to %1%"), export_path));
} }
// A print host upload job has been scheduled, enqueue it to the printhost job queue // A print host upload job has been scheduled, enqueue it to the printhost job queue
@ -716,10 +716,10 @@ void BackgroundSlicingProcess::prepare_upload()
/ boost::filesystem::unique_path("." SLIC3R_APP_KEY ".upload.%%%%-%%%%-%%%%-%%%%"); / boost::filesystem::unique_path("." SLIC3R_APP_KEY ".upload.%%%%-%%%%-%%%%-%%%%");
if (m_print == m_fff_print) { if (m_print == m_fff_print) {
m_print->set_status(95, _utf8(L("Running post-processing scripts"))); m_print->set_status(95, _u8L("Running post-processing scripts"));
std::string error_message; std::string error_message;
if (copy_file(m_temp_output_path, source_path.string(), error_message) != SUCCESS) if (copy_file(m_temp_output_path, source_path.string(), error_message) != SUCCESS)
throw Slic3r::RuntimeError(_utf8(L("Copying of the temporary G-code to the output G-code failed"))); throw Slic3r::RuntimeError(_u8L("Copying of the temporary G-code to the output G-code failed"));
m_upload_job.upload_data.upload_path = m_fff_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string()); m_upload_job.upload_data.upload_path = m_fff_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string());
// Make a copy of the source path, as run_post_process_scripts() is allowed to change it when making a copy of the source file // Make a copy of the source path, as run_post_process_scripts() is allowed to change it when making a copy of the source file
// (not here, but when the final target is a file). // (not here, but when the final target is a file).
@ -735,7 +735,7 @@ void BackgroundSlicingProcess::prepare_upload()
m_sla_print->export_print(source_path.string(),thumbnails, m_upload_job.upload_data.upload_path.filename().string()); m_sla_print->export_print(source_path.string(),thumbnails, m_upload_job.upload_data.upload_path.filename().string());
} }
m_print->set_status(100, (boost::format(_utf8(L("Scheduling upload to `%1%`. See Window -> Print Host Upload Queue"))) % m_upload_job.printhost->get_host()).str()); m_print->set_status(100, GUI::format(_L("Scheduling upload to `%1%`. See Window -> Print Host Upload Queue"), m_upload_job.printhost->get_host()));
m_upload_job.upload_data.source_path = std::move(source_path); m_upload_job.upload_data.source_path = std::move(source_path);

View File

@ -128,6 +128,9 @@ void BedShape::apply_optgroup_values(ConfigOptionsGroupShp optgroup)
} }
} }
BedShapeDialog::BedShapeDialog(wxWindow* parent) : DPIDialog(parent, wxID_ANY, _(L("Bed Shape")),
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {}
void BedShapeDialog::build_dialog(const ConfigOptionPoints& default_pt, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model) void BedShapeDialog::build_dialog(const ConfigOptionPoints& default_pt, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model)
{ {
SetFont(wxGetApp().normal_font()); SetFont(wxGetApp().normal_font());

View File

@ -5,7 +5,6 @@
#include "GUI_Utils.hpp" #include "GUI_Utils.hpp"
#include "2DBed.hpp" #include "2DBed.hpp"
#include "I18N.hpp"
#include <libslic3r/BuildVolume.hpp> #include <libslic3r/BuildVolume.hpp>
@ -93,8 +92,7 @@ class BedShapeDialog : public DPIDialog
{ {
BedShapePanel* m_panel; BedShapePanel* m_panel;
public: public:
BedShapeDialog(wxWindow* parent) : DPIDialog(parent, wxID_ANY, _(L("Bed Shape")), BedShapeDialog(wxWindow* parent);
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {}
void build_dialog(const ConfigOptionPoints& default_pt, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model); void build_dialog(const ConfigOptionPoints& default_pt, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model);

View File

@ -224,14 +224,14 @@ void BonjourDialog::on_timer(wxTimerEvent &)
// explicitly (wxTimerEvent should not be created by user code). // explicitly (wxTimerEvent should not be created by user code).
void BonjourDialog::on_timer_process() void BonjourDialog::on_timer_process()
{ {
const auto search_str = _utf8(L("Searching for devices")); const auto search_str = _L("Searching for devices");
if (timer_state > 0) { if (timer_state > 0) {
const std::string dots(timer_state, '.'); const std::string dots(timer_state, '.');
label->SetLabel(GUI::from_u8((boost::format("%1% %2%") % search_str % dots).str())); label->SetLabel(search_str + dots);
timer_state = (timer_state) % 3 + 1; timer_state = (timer_state) % 3 + 1;
} else { } else {
label->SetLabel(GUI::from_u8((boost::format("%1%: %2%") % search_str % (_utf8(L("Finished"))+".")).str())); label->SetLabel(search_str + ": " + _L("Finished") + ".");
timer->Stop(); timer->Stop();
} }
} }

View File

@ -160,7 +160,7 @@ void FillSizerWithModeColorDescriptions(
wxFlexGridSizer* grid_sizer = new wxFlexGridSizer(9, 5, 5); wxFlexGridSizer* grid_sizer = new wxFlexGridSizer(9, 5, 5);
sizer->Add(grid_sizer, 0, wxEXPAND); sizer->Add(grid_sizer, 0, wxEXPAND);
const std::vector<wxString> names = { _L("Simple"), _CTX(L_CONTEXT("Advanced", "Mode"), "Mode"), _L("Expert") }; const std::vector<wxString> names = { _L("Simple"), _CTX("Advanced", "Mode"), _L("Expert") };
for (size_t mode = 0; mode < names.size(); ++mode) { for (size_t mode = 0; mode < names.size(); ++mode) {
wxColour& color = mode_palette[mode]; wxColour& color = mode_palette[mode];

View File

@ -319,8 +319,8 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
toggle_field("standby_temperature_delta", have_ooze_prevention); toggle_field("standby_temperature_delta", have_ooze_prevention);
bool have_wipe_tower = config->opt_bool("wipe_tower"); bool have_wipe_tower = config->opt_bool("wipe_tower");
for (auto el : { "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim_width", for (auto el : { "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_cone_angle",
"wipe_tower_bridging", "wipe_tower_no_sparse_layers", "single_extruder_multi_material_priming" }) "wipe_tower_extra_spacing", "wipe_tower_bridging", "wipe_tower_no_sparse_layers", "single_extruder_multi_material_priming" })
toggle_field(el, have_wipe_tower); toggle_field(el, have_wipe_tower);
toggle_field("avoid_crossing_curled_overhangs", !config->opt_bool("avoid_crossing_perimeters")); toggle_field("avoid_crossing_curled_overhangs", !config->opt_bool("avoid_crossing_perimeters"));

View File

@ -89,10 +89,10 @@ static wxString generate_html_row(const Config::Snapshot &snapshot, bool row_eve
} }
if (! compatible) { if (! compatible) {
text += "<p align=\"right\">" + from_u8((boost::format(_utf8(L("Incompatible with this %s"))) % SLIC3R_APP_NAME).str()) + "</p>"; text += "<p align=\"right\">" + format_wxstr(_L("Incompatible with this %s"), SLIC3R_APP_NAME) + "</p>";
} }
else if (! snapshot_active) else if (! snapshot_active)
text += "<p align=\"right\"><a href=\"" + snapshot.id + "\">" + _(L("Activate")) + "</a></p>"; text += "<p align=\"right\"><a href=\"" + snapshot.id + "\">" + _L("Activate") + "</a></p>";
text += "</td>"; text += "</td>";
text += "</tr>"; text += "</tr>";
return text; return text;

View File

@ -56,6 +56,7 @@
#include "MsgDialog.hpp" #include "MsgDialog.hpp"
#include "UnsavedChangesDialog.hpp" #include "UnsavedChangesDialog.hpp"
#include "slic3r/Utils/AppUpdater.hpp" #include "slic3r/Utils/AppUpdater.hpp"
#include "slic3r/GUI/I18N.hpp"
#if defined(__linux__) && defined(__WXGTK3__) #if defined(__linux__) && defined(__WXGTK3__)
#define wxLinux_gtk3 true #define wxLinux_gtk3 true
@ -288,7 +289,7 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxSt
const auto &variant = model.variants[i]; const auto &variant = model.variants[i];
const auto label = model.technology == ptFFF const auto label = model.technology == ptFFF
? from_u8((boost::format("%1% %2% %3%") % variant.name % _utf8(L("mm")) % _utf8(L("nozzle"))).str()) ? format_wxstr("%1% %2% %3%", variant.name, _L("mm"), _L("nozzle"))
: from_u8(model.name); : from_u8(model.name);
if (i == 1) { if (i == 1) {
@ -508,17 +509,17 @@ void ConfigWizardPage::append_spacer(int space)
// Wizard pages // Wizard pages
PageWelcome::PageWelcome(ConfigWizard *parent) PageWelcome::PageWelcome(ConfigWizard *parent)
: ConfigWizardPage(parent, from_u8((boost::format( : ConfigWizardPage(parent, format_wxstr(
#ifdef __APPLE__ #ifdef __APPLE__
_utf8(L("Welcome to the %s Configuration Assistant")) _L("Welcome to the %s Configuration Assistant")
#else #else
_utf8(L("Welcome to the %s Configuration Wizard")) _L("Welcome to the %s Configuration Wizard")
#endif #endif
) % SLIC3R_APP_NAME).str()), _L("Welcome")) , SLIC3R_APP_NAME), _L("Welcome"))
, welcome_text(append_text(from_u8((boost::format( , welcome_text(append_text(format_wxstr(
_utf8(L("Hello, welcome to %s! This %s helps you with the initial configuration; just a few settings and you will be ready to print."))) _L("Hello, welcome to %s! This %s helps you with the initial configuration; just a few settings and you will be ready to print.")
% SLIC3R_APP_NAME , SLIC3R_APP_NAME
% _utf8(ConfigWizard::name())).str()) , _(ConfigWizard::name()))
)) ))
, cbox_reset(append( , cbox_reset(append(
new wxCheckBox(this, wxID_ANY, _L("Remove user profiles (a snapshot will be taken beforehand)")) new wxCheckBox(this, wxID_ANY, _L("Remove user profiles (a snapshot will be taken beforehand)"))
@ -576,7 +577,7 @@ PagePrinters::PagePrinters(ConfigWizard *parent,
continue; continue;
} }
const auto picker_title = family.empty() ? wxString() : from_u8((boost::format(_utf8(L("%s Family"))) % family).str()); const auto picker_title = family.empty() ? wxString() : format_wxstr(_L("%s Family"), family);
auto *picker = new PrinterPicker(this, vendor, picker_title, MAX_COLS, *appconfig, filter); auto *picker = new PrinterPicker(this, vendor, picker_title, MAX_COLS, *appconfig, filter);
picker->Bind(EVT_PRINTER_PICK, [this, appconfig](const PrinterPickerEvent &evt) { picker->Bind(EVT_PRINTER_PICK, [this, appconfig](const PrinterPickerEvent &evt) {
@ -786,11 +787,14 @@ void PageMaterials::set_compatible_printers_html_window(const std::vector<std::s
const auto text_clr_str = encode_color(ColorRGB(text_clr.Red(), text_clr.Green(), text_clr.Blue())); const auto text_clr_str = encode_color(ColorRGB(text_clr.Red(), text_clr.Green(), text_clr.Blue()));
wxString text; wxString text;
if (materials->technology == T_FFF && template_shown) { if (materials->technology == T_FFF && template_shown) {
// TRN ConfigWizard: Materials : "%1%" = "Filaments"/"SLA materials"
text = format_wxstr(_L("%1% visible for <b>(\"Template\")</b> printer are universal profiles available for all printers. These might not be compatible with your printer."), materials->technology == T_FFF ? _L("Filaments") : _L("SLA materials")); text = format_wxstr(_L("%1% visible for <b>(\"Template\")</b> printer are universal profiles available for all printers. These might not be compatible with your printer."), materials->technology == T_FFF ? _L("Filaments") : _L("SLA materials"));
} else { } else {
// TRN ConfigWizard: Materials : "%1%" = "Filaments"/"SLA materials"
wxString first_line = format_wxstr(_L("%1% marked with <b>*</b> are <b>not</b> compatible with some installed printers."), materials->technology == T_FFF ? _L("Filaments") : _L("SLA materials")); wxString first_line = format_wxstr(_L("%1% marked with <b>*</b> are <b>not</b> compatible with some installed printers."), materials->technology == T_FFF ? _L("Filaments") : _L("SLA materials"));
if (all_printers) { if (all_printers) {
// TRN ConfigWizard: Materials : "%1%" = "filament"/"SLA material"
wxString second_line = format_wxstr(_L("All installed printers are compatible with the selected %1%."), materials->technology == T_FFF ? _L("filament") : _L("SLA material")); wxString second_line = format_wxstr(_L("All installed printers are compatible with the selected %1%."), materials->technology == T_FFF ? _L("filament") : _L("SLA material"));
text = wxString::Format( text = wxString::Format(
"<html>" "<html>"
@ -1368,7 +1372,7 @@ Worker::Worker(wxWindow* parent)
button_path->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) { button_path->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) {
boost::filesystem::path chosen_dest(boost::nowide::narrow(m_input_path->GetValue())); boost::filesystem::path chosen_dest(boost::nowide::narrow(m_input_path->GetValue()));
wxDirDialog dialog(m_parent, L("Choose folder:"), chosen_dest.string() ); wxDirDialog dialog(m_parent, _L("Choose folder") + ":", chosen_dest.string() );
if (dialog.ShowModal() == wxID_OK) if (dialog.ShowModal() == wxID_OK)
this->m_input_path->SetValue(dialog.GetPath()); this->m_input_path->SetValue(dialog.GetPath());
}); });
@ -1420,11 +1424,12 @@ PageDownloader::PageDownloader(ConfigWizard* parent)
box_allow_downloads->SetValue(box_allow_value); box_allow_downloads->SetValue(box_allow_value);
append(box_allow_downloads); append(box_allow_downloads);
append_text(wxString::Format(_L( // TRN ConfigWizard : Downloader : %1% = "PrusaSlicer"
"If enabled, %s registers to start on custom URL on www.printables.com." append_text(format_wxstr(_L(
" You will be able to use button with %s logo to open models in this %s." "If enabled, %1% registers to start on custom URL on www.printables.com."
" You will be able to use button with %1% logo to open models in this %1%."
" The model will be downloaded into folder you choose bellow." " The model will be downloaded into folder you choose bellow."
), SLIC3R_APP_NAME, SLIC3R_APP_NAME, SLIC3R_APP_NAME)); ), SLIC3R_APP_NAME));
#ifdef __linux__ #ifdef __linux__
append_text(wxString::Format(_L( append_text(wxString::Format(_L(
@ -1455,7 +1460,7 @@ bool DownloaderUtils::Worker::perform_register(const std::string& path_override/
chosen_dest = aux_dest; chosen_dest = aux_dest;
ec.clear(); ec.clear();
if (chosen_dest.empty() || !boost::filesystem::is_directory(chosen_dest, ec) || ec) { if (chosen_dest.empty() || !boost::filesystem::is_directory(chosen_dest, ec) || ec) {
std::string err_msg = GUI::format("%1%\n\n%2%",_L("Chosen directory for downloads does not Exists.") ,chosen_dest.string()); std::string err_msg = GUI::format("%1%\n\n%2%",_L("Chosen directory for downloads does not exist.") ,chosen_dest.string());
BOOST_LOG_TRIVIAL(error) << err_msg; BOOST_LOG_TRIVIAL(error) << err_msg;
show_error(m_parent, err_msg); show_error(m_parent, err_msg);
return false; return false;
@ -1752,6 +1757,7 @@ void PageBedShape::apply_custom_config(DynamicPrintConfig &config)
} }
PageBuildVolume::PageBuildVolume(ConfigWizard* parent) PageBuildVolume::PageBuildVolume(ConfigWizard* parent)
// TRN ConfigWizard : Size of possible print, related on printer size
: ConfigWizardPage(parent, _L("Build Volume"), _L("Build Volume"), 1) : ConfigWizardPage(parent, _L("Build Volume"), _L("Build Volume"), 1)
, build_volume(new DiamTextCtrl(this)) , build_volume(new DiamTextCtrl(this))
{ {
@ -1792,7 +1798,7 @@ PageBuildVolume::PageBuildVolume(ConfigWizard* parent)
}, build_volume->GetId()); }, build_volume->GetId());
auto* sizer_volume = new wxFlexGridSizer(3, 5, 5); auto* sizer_volume = new wxFlexGridSizer(3, 5, 5);
auto* text_volume = new wxStaticText(this, wxID_ANY, _L("Max print height:")); auto* text_volume = new wxStaticText(this, wxID_ANY, _L("Max print height") + ":");
auto* unit_volume = new wxStaticText(this, wxID_ANY, _L("mm")); auto* unit_volume = new wxStaticText(this, wxID_ANY, _L("mm"));
sizer_volume->AddGrowableCol(0, 1); sizer_volume->AddGrowableCol(0, 1);
sizer_volume->Add(text_volume, 0, wxALIGN_CENTRE_VERTICAL); sizer_volume->Add(text_volume, 0, wxALIGN_CENTRE_VERTICAL);
@ -1828,7 +1834,7 @@ PageDiameters::PageDiameters(ConfigWizard *parent)
append_text(_L("Enter the diameter of your printer's hot end nozzle.")); append_text(_L("Enter the diameter of your printer's hot end nozzle."));
auto *sizer_nozzle = new wxFlexGridSizer(3, 5, 5); auto *sizer_nozzle = new wxFlexGridSizer(3, 5, 5);
auto *text_nozzle = new wxStaticText(this, wxID_ANY, _L("Nozzle Diameter:")); auto *text_nozzle = new wxStaticText(this, wxID_ANY, _L("Nozzle Diameter") + ":");
auto *unit_nozzle = new wxStaticText(this, wxID_ANY, _L("mm")); auto *unit_nozzle = new wxStaticText(this, wxID_ANY, _L("mm"));
sizer_nozzle->AddGrowableCol(0, 1); sizer_nozzle->AddGrowableCol(0, 1);
sizer_nozzle->Add(text_nozzle, 0, wxALIGN_CENTRE_VERTICAL); sizer_nozzle->Add(text_nozzle, 0, wxALIGN_CENTRE_VERTICAL);
@ -1842,7 +1848,7 @@ PageDiameters::PageDiameters(ConfigWizard *parent)
append_text(_L("Good precision is required, so use a caliper and do multiple measurements along the filament, then compute the average.")); append_text(_L("Good precision is required, so use a caliper and do multiple measurements along the filament, then compute the average."));
auto *sizer_filam = new wxFlexGridSizer(3, 5, 5); auto *sizer_filam = new wxFlexGridSizer(3, 5, 5);
auto *text_filam = new wxStaticText(this, wxID_ANY, _L("Filament Diameter:")); auto *text_filam = new wxStaticText(this, wxID_ANY, _L("Filament Diameter") + ":");
auto *unit_filam = new wxStaticText(this, wxID_ANY, _L("mm")); auto *unit_filam = new wxStaticText(this, wxID_ANY, _L("mm"));
sizer_filam->AddGrowableCol(0, 1); sizer_filam->AddGrowableCol(0, 1);
sizer_filam->Add(text_filam, 0, wxALIGN_CENTRE_VERTICAL); sizer_filam->Add(text_filam, 0, wxALIGN_CENTRE_VERTICAL);
@ -1934,7 +1940,7 @@ PageTemperatures::PageTemperatures(ConfigWizard *parent)
append_text(_L("A rule of thumb is 60 °C for PLA and 110 °C for ABS. Leave zero if you have no heated bed.")); append_text(_L("A rule of thumb is 60 °C for PLA and 110 °C for ABS. Leave zero if you have no heated bed."));
auto *sizer_bed = new wxFlexGridSizer(3, 5, 5); auto *sizer_bed = new wxFlexGridSizer(3, 5, 5);
auto *text_bed = new wxStaticText(this, wxID_ANY, _L("Bed Temperature:")); auto *text_bed = new wxStaticText(this, wxID_ANY, _L("Bed Temperature") + ":");
auto *unit_bed = new wxStaticText(this, wxID_ANY, _L("°C")); auto *unit_bed = new wxStaticText(this, wxID_ANY, _L("°C"));
sizer_bed->AddGrowableCol(0, 1); sizer_bed->AddGrowableCol(0, 1);
sizer_bed->Add(text_bed, 0, wxALIGN_CENTRE_VERTICAL); sizer_bed->Add(text_bed, 0, wxALIGN_CENTRE_VERTICAL);

View File

@ -106,7 +106,7 @@ Control::Control( wxWindow *parent,
m_cog_icon_dim = m_bmp_cog.GetWidth(); m_cog_icon_dim = m_bmp_cog.GetWidth();
m_selection = ssUndef; m_selection = ssUndef;
m_ticks.set_pause_print_msg(_utf8(L("Place bearings in slots and resume printing"))); m_ticks.set_pause_print_msg(_u8L("Place bearings in slots and resume printing"));
m_ticks.set_extruder_colors(&m_extruder_colors); m_ticks.set_extruder_colors(&m_extruder_colors);
// slider events // slider events

View File

@ -178,7 +178,7 @@ void Downloader::on_error(wxCommandEvent& event)
BOOST_LOG_TRIVIAL(error) << "Download error: " << event.GetString(); BOOST_LOG_TRIVIAL(error) << "Download error: " << event.GetString();
NotificationManager* ntf_mngr = wxGetApp().notification_manager(); NotificationManager* ntf_mngr = wxGetApp().notification_manager();
ntf_mngr->set_download_URL_error(id, boost::nowide::narrow(event.GetString())); ntf_mngr->set_download_URL_error(id, boost::nowide::narrow(event.GetString()));
show_error(nullptr, format_wxstr(L"%1%\n%2%", _L("The download has failed:"), event.GetString())); show_error(nullptr, format_wxstr(L"%1%\n%2%", _L("The download has failed") + ":", event.GetString()));
} }
void Downloader::on_complete(wxCommandEvent& event) void Downloader::on_complete(wxCommandEvent& event)
{ {

View File

@ -190,6 +190,7 @@ void FileGet::priv::get_perform()
//assert(file != NULL); //assert(file != NULL);
if (file == NULL) { if (file == NULL) {
wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_ERROR); wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_ERROR);
// TRN %1% = file path
evt->SetString(GUI::format_wxstr(_L("Can't create file at %1%."), temp_path_wstring)); evt->SetString(GUI::format_wxstr(_L("Can't create file at %1%."), temp_path_wstring));
evt->SetInt(m_id); evt->SetInt(m_id);
m_evt_handler->QueueEvent(evt); m_evt_handler->QueueEvent(evt);

View File

@ -226,7 +226,7 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
} }
wxString label = m_opt.full_label.empty() ? _(m_opt.label) : _(m_opt.full_label); wxString label = m_opt.full_label.empty() ? _(m_opt.label) : _(m_opt.full_label);
show_error(m_parent, from_u8((boost::format(_utf8(L("%s doesn't support percentage"))) % label).str())); show_error(m_parent, format_wxstr(_L("%s doesn't support percentage"), label));
set_value(double_to_string(m_opt.min), true); set_value(double_to_string(m_opt.min), true);
m_value = double(m_opt.min); m_value = double(m_opt.min);
break; break;
@ -299,7 +299,7 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
// Workaroud to avoid of using of the % for first layer height // Workaroud to avoid of using of the % for first layer height
// see https://github.com/prusa3d/PrusaSlicer/issues/7418 // see https://github.com/prusa3d/PrusaSlicer/issues/7418
wxString label = m_opt.full_label.empty() ? _(m_opt.label) : _(m_opt.full_label); wxString label = m_opt.full_label.empty() ? _(m_opt.label) : _(m_opt.full_label);
show_error(m_parent, from_u8((boost::format(_utf8(L("%s doesn't support percentage"))) % label).str())); show_error(m_parent, format_wxstr(_L("%s doesn't support percentage"), label));
const wxString stVal = double_to_string(0.01, 2); const wxString stVal = double_to_string(0.01, 2);
set_value(stVal, true); set_value(stVal, true);
m_value = into_u8(stVal);; m_value = into_u8(stVal);;
@ -341,9 +341,10 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
const std::string sidetext = m_opt.sidetext.rfind("mm/s") != std::string::npos ? "mm/s" : "mm"; const std::string sidetext = m_opt.sidetext.rfind("mm/s") != std::string::npos ? "mm/s" : "mm";
const wxString stVal = double_to_string(val, 2); const wxString stVal = double_to_string(val, 2);
const wxString msg_text = from_u8((boost::format(_utf8(L("Do you mean %s%% instead of %s %s?\n" // TRN %1% = Value, %2% = units
"Select YES if you want to change this value to %s%%, \n" const wxString msg_text = format_wxstr(_L("Do you mean %1%%% instead of %1% %2%?\n"
"or NO if you are sure that %s %s is a correct value."))) % stVal % stVal % sidetext % stVal % stVal % sidetext).str()); "Select YES if you want to change this value to %1%%%, \n"
"or NO if you are sure that %1% %2% is a correct value."), stVal, sidetext);
WarningDialog dialog(m_parent, msg_text, _L("Parameter validation") + ": " + m_opt_id, wxYES | wxNO); WarningDialog dialog(m_parent, msg_text, _L("Parameter validation") + ": " + m_opt_id, wxYES | wxNO);
if ((!infill_anchors || val > 100) && dialog.ShowModal() == wxID_YES) { if ((!infill_anchors || val > 100) && dialog.ShowModal() == wxID_YES) {
set_value(from_u8((boost::format("%s%%") % stVal).str()), false/*true*/); set_value(from_u8((boost::format("%s%%") % stVal).str()), false/*true*/);

View File

@ -2253,7 +2253,7 @@ void GCodeViewer::load_shells(const Print& print)
const WipeTowerData& wipe_tower_data = print.wipe_tower_data(extruders_count); const WipeTowerData& wipe_tower_data = print.wipe_tower_data(extruders_count);
const float depth = wipe_tower_data.depth; const float depth = wipe_tower_data.depth;
const float brim_width = wipe_tower_data.brim_width; const float brim_width = wipe_tower_data.brim_width;
m_shells.volumes.load_wipe_tower_preview(config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle, m_shells.volumes.load_wipe_tower_preview(config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_cone_angle, config.wipe_tower_rotation_angle,
!print.is_step_done(psWipeTower), brim_width); !print.is_step_done(psWipeTower), brim_width);
} }
} }

View File

@ -728,7 +728,7 @@ void GLCanvas3D::Labels::render(const std::vector<const ModelInstance*>& sorted_
return owner.model_instance_id == id; return owner.model_instance_id == id;
}); });
if (it != owners.end()) if (it != owners.end())
it->print_order = std::string((_(L("Seq."))).ToUTF8()) + "#: " + std::to_string(i + 1); it->print_order = _u8L("Seq.") + "#: " + std::to_string(i + 1);
} }
} }
@ -2144,17 +2144,18 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
const float w = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_width"))->value; const float w = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_width"))->value;
const float a = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_rotation_angle"))->value; const float a = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_rotation_angle"))->value;
const float bw = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_brim_width"))->value; const float bw = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_brim_width"))->value;
const float ca = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_cone_angle"))->value;
const Print *print = m_process->fff_print(); const Print *print = m_process->fff_print();
const float depth = print->wipe_tower_data(extruders_count).depth; const float depth = print->wipe_tower_data(extruders_count).depth;
#if ENABLE_OPENGL_ES #if ENABLE_OPENGL_ES
int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview( int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview(
x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower), x, y, w, depth, (float)height, ca, a, !print->is_step_done(psWipeTower),
bw, &m_wipe_tower_mesh); bw, &m_wipe_tower_mesh);
#else #else
int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview( int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview(
x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower), x, y, w, depth, (float)height, ca, a, !print->is_step_done(psWipeTower),
bw); bw);
#endif // ENABLE_OPENGL_ES #endif // ENABLE_OPENGL_ES
if (volume_idx_wipe_tower_old != -1) if (volume_idx_wipe_tower_old != -1)
@ -4819,7 +4820,7 @@ bool GLCanvas3D::_init_main_toolbar()
item.name = "add"; item.name = "add";
item.icon_filename = "add.svg"; item.icon_filename = "add.svg";
item.tooltip = _utf8(L("Add...")) + " [" + GUI::shortkey_ctrl_prefix() + "I]"; item.tooltip = _u8L("Add...") + " [" + GUI::shortkey_ctrl_prefix() + "I]";
item.sprite_id = 0; item.sprite_id = 0;
item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_ADD)); }; item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_ADD)); };
if (!m_main_toolbar.add_item(item)) if (!m_main_toolbar.add_item(item))
@ -4827,7 +4828,7 @@ bool GLCanvas3D::_init_main_toolbar()
item.name = "delete"; item.name = "delete";
item.icon_filename = "remove.svg"; item.icon_filename = "remove.svg";
item.tooltip = _utf8(L("Delete")) + " [Del]"; item.tooltip = _u8L("Delete") + " [Del]";
item.sprite_id = 1; item.sprite_id = 1;
item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_DELETE)); }; item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_DELETE)); };
item.enabling_callback = []()->bool { return wxGetApp().plater()->can_delete(); }; item.enabling_callback = []()->bool { return wxGetApp().plater()->can_delete(); };
@ -4836,7 +4837,7 @@ bool GLCanvas3D::_init_main_toolbar()
item.name = "deleteall"; item.name = "deleteall";
item.icon_filename = "delete_all.svg"; item.icon_filename = "delete_all.svg";
item.tooltip = _utf8(L("Delete all")) + " [" + GUI::shortkey_ctrl_prefix() + "Del]"; item.tooltip = _u8L("Delete all") + " [" + GUI::shortkey_ctrl_prefix() + "Del]";
item.sprite_id = 2; item.sprite_id = 2;
item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_DELETE_ALL)); }; item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_DELETE_ALL)); };
item.enabling_callback = []()->bool { return wxGetApp().plater()->can_delete_all(); }; item.enabling_callback = []()->bool { return wxGetApp().plater()->can_delete_all(); };
@ -4845,7 +4846,7 @@ bool GLCanvas3D::_init_main_toolbar()
item.name = "arrange"; item.name = "arrange";
item.icon_filename = "arrange.svg"; item.icon_filename = "arrange.svg";
item.tooltip = _utf8(L("Arrange")) + " [A]\n" + _utf8(L("Arrange selection")) + " [Shift+A]\n" + _utf8(L("Click right mouse button to show arrangement options")); item.tooltip = _u8L("Arrange") + " [A]\n" + _u8L("Arrange selection") + " [Shift+A]\n" + _u8L("Click right mouse button to show arrangement options");
item.sprite_id = 3; item.sprite_id = 3;
item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_ARRANGE)); }; item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_ARRANGE)); };
item.enabling_callback = []()->bool { return wxGetApp().plater()->can_arrange(); }; item.enabling_callback = []()->bool { return wxGetApp().plater()->can_arrange(); };
@ -4865,7 +4866,7 @@ bool GLCanvas3D::_init_main_toolbar()
item.name = "copy"; item.name = "copy";
item.icon_filename = "copy.svg"; item.icon_filename = "copy.svg";
item.tooltip = _utf8(L("Copy")) + " [" + GUI::shortkey_ctrl_prefix() + "C]"; item.tooltip = _u8L("Copy") + " [" + GUI::shortkey_ctrl_prefix() + "C]";
item.sprite_id = 4; item.sprite_id = 4;
item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_COPY)); }; item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_COPY)); };
item.enabling_callback = []()->bool { return wxGetApp().plater()->can_copy_to_clipboard(); }; item.enabling_callback = []()->bool { return wxGetApp().plater()->can_copy_to_clipboard(); };
@ -4874,7 +4875,7 @@ bool GLCanvas3D::_init_main_toolbar()
item.name = "paste"; item.name = "paste";
item.icon_filename = "paste.svg"; item.icon_filename = "paste.svg";
item.tooltip = _utf8(L("Paste")) + " [" + GUI::shortkey_ctrl_prefix() + "V]"; item.tooltip = _u8L("Paste") + " [" + GUI::shortkey_ctrl_prefix() + "V]";
item.sprite_id = 5; item.sprite_id = 5;
item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_PASTE)); }; item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_PASTE)); };
item.enabling_callback = []()->bool { return wxGetApp().plater()->can_paste_from_clipboard(); }; item.enabling_callback = []()->bool { return wxGetApp().plater()->can_paste_from_clipboard(); };
@ -4886,7 +4887,7 @@ bool GLCanvas3D::_init_main_toolbar()
item.name = "more"; item.name = "more";
item.icon_filename = "instance_add.svg"; item.icon_filename = "instance_add.svg";
item.tooltip = _utf8(L("Add instance")) + " [+]"; item.tooltip = _u8L("Add instance") + " [+]";
item.sprite_id = 6; item.sprite_id = 6;
item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_MORE)); }; item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_MORE)); };
item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; }; item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; };
@ -4897,7 +4898,7 @@ bool GLCanvas3D::_init_main_toolbar()
item.name = "fewer"; item.name = "fewer";
item.icon_filename = "instance_remove.svg"; item.icon_filename = "instance_remove.svg";
item.tooltip = _utf8(L("Remove instance")) + " [-]"; item.tooltip = _u8L("Remove instance") + " [-]";
item.sprite_id = 7; item.sprite_id = 7;
item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_FEWER)); }; item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_FEWER)); };
item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; }; item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; };
@ -4910,7 +4911,7 @@ bool GLCanvas3D::_init_main_toolbar()
item.name = "splitobjects"; item.name = "splitobjects";
item.icon_filename = "split_objects.svg"; item.icon_filename = "split_objects.svg";
item.tooltip = _utf8(L("Split to objects")); item.tooltip = _u8L("Split to objects");
item.sprite_id = 8; item.sprite_id = 8;
item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_SPLIT_OBJECTS)); }; item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_SPLIT_OBJECTS)); };
item.visibility_callback = GLToolbarItem::Default_Visibility_Callback; item.visibility_callback = GLToolbarItem::Default_Visibility_Callback;
@ -4920,7 +4921,7 @@ bool GLCanvas3D::_init_main_toolbar()
item.name = "splitvolumes"; item.name = "splitvolumes";
item.icon_filename = "split_parts.svg"; item.icon_filename = "split_parts.svg";
item.tooltip = _utf8(L("Split to parts")); item.tooltip = _u8L("Split to parts");
item.sprite_id = 9; item.sprite_id = 9;
item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_SPLIT_VOLUMES)); }; item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_SPLIT_VOLUMES)); };
item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; }; item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; };
@ -4934,8 +4935,8 @@ bool GLCanvas3D::_init_main_toolbar()
item.name = "settings"; item.name = "settings";
item.icon_filename = "settings.svg"; item.icon_filename = "settings.svg";
item.tooltip = _u8L("Switch to Settings") + "\n" + "[" + GUI::shortkey_ctrl_prefix() + "2] - " + _u8L("Print Settings Tab") + item.tooltip = _u8L("Switch to Settings") + "\n" + "[" + GUI::shortkey_ctrl_prefix() + "2] - " + _u8L("Print Settings Tab") +
"\n" + "[" + GUI::shortkey_ctrl_prefix() + "3] - " + (current_printer_technology() == ptFFF ? _u8L("Filament Settings Tab") : _u8L("Material Settings Tab")) + "\n" + "[" + GUI::shortkey_ctrl_prefix() + "3] - " + (current_printer_technology() == ptFFF ? _u8L("Filament Settings Tab") : _u8L("Material Settings Tab") +
"\n" + "[" + GUI::shortkey_ctrl_prefix() + "4] - " + _u8L("Printer Settings Tab") ; "\n" + "[" + GUI::shortkey_ctrl_prefix() + "4] - " + _u8L("Printer Settings Tab")) ;
item.sprite_id = 10; item.sprite_id = 10;
item.enabling_callback = GLToolbarItem::Default_Enabling_Callback; item.enabling_callback = GLToolbarItem::Default_Enabling_Callback;
item.visibility_callback = []() { return wxGetApp().app_config->get_bool("new_settings_layout_mode") || item.visibility_callback = []() { return wxGetApp().app_config->get_bool("new_settings_layout_mode") ||
@ -4951,7 +4952,7 @@ bool GLCanvas3D::_init_main_toolbar()
item.name = "search"; item.name = "search";
item.icon_filename = "search_.svg"; item.icon_filename = "search_.svg";
item.tooltip = _utf8(L("Search")) + " [" + GUI::shortkey_ctrl_prefix() + "F]"; item.tooltip = _u8L("Search") + " [" + GUI::shortkey_ctrl_prefix() + "F]";
item.sprite_id = 11; item.sprite_id = 11;
item.left.toggable = true; item.left.toggable = true;
item.left.render_callback = [this](float left, float right, float, float) { item.left.render_callback = [this](float left, float right, float, float) {
@ -4973,7 +4974,7 @@ bool GLCanvas3D::_init_main_toolbar()
item.name = "layersediting"; item.name = "layersediting";
item.icon_filename = "layers_white.svg"; item.icon_filename = "layers_white.svg";
item.tooltip = _utf8(L("Variable layer height")); item.tooltip = _u8L("Variable layer height");
item.sprite_id = 12; item.sprite_id = 12;
item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING)); }; item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING)); };
item.visibility_callback = [this]()->bool { item.visibility_callback = [this]()->bool {
@ -5026,7 +5027,7 @@ bool GLCanvas3D::_init_undoredo_toolbar()
item.name = "undo"; item.name = "undo";
item.icon_filename = "undo_toolbar.svg"; item.icon_filename = "undo_toolbar.svg";
item.tooltip = _utf8(L("Undo")) + " [" + GUI::shortkey_ctrl_prefix() + "Z]\n" + _utf8(L("Click right mouse button to open/close History")); item.tooltip = _u8L("Undo") + " [" + GUI::shortkey_ctrl_prefix() + "Z]\n" + _u8L("Click right mouse button to open/close History");
item.sprite_id = 0; item.sprite_id = 0;
item.left.action_callback = [this]() { post_event(SimpleEvent(EVT_GLCANVAS_UNDO)); }; item.left.action_callback = [this]() { post_event(SimpleEvent(EVT_GLCANVAS_UNDO)); };
item.right.toggable = true; item.right.toggable = true;
@ -5048,7 +5049,7 @@ bool GLCanvas3D::_init_undoredo_toolbar()
if (can_undo) { if (can_undo) {
std::string action; std::string action;
wxGetApp().plater()->undo_redo_topmost_string_getter(true, action); wxGetApp().plater()->undo_redo_topmost_string_getter(true, action);
new_additional_tooltip = (boost::format(_utf8(L("Next Undo action: %1%"))) % action).str(); new_additional_tooltip = format(_L("Next Undo action: %1%"), action);
} }
if (new_additional_tooltip != curr_additional_tooltip) { if (new_additional_tooltip != curr_additional_tooltip) {
@ -5063,7 +5064,7 @@ bool GLCanvas3D::_init_undoredo_toolbar()
item.name = "redo"; item.name = "redo";
item.icon_filename = "redo_toolbar.svg"; item.icon_filename = "redo_toolbar.svg";
item.tooltip = _utf8(L("Redo")) + " [" + GUI::shortkey_ctrl_prefix() + "Y]\n" + _utf8(L("Click right mouse button to open/close History")); item.tooltip = _u8L("Redo") + " [" + GUI::shortkey_ctrl_prefix() + "Y]\n" + _u8L("Click right mouse button to open/close History");
item.sprite_id = 1; item.sprite_id = 1;
item.left.action_callback = [this]() { post_event(SimpleEvent(EVT_GLCANVAS_REDO)); }; item.left.action_callback = [this]() { post_event(SimpleEvent(EVT_GLCANVAS_REDO)); };
item.right.action_callback = [this]() { m_imgui_undo_redo_hovered_pos = -1; }; item.right.action_callback = [this]() { m_imgui_undo_redo_hovered_pos = -1; };
@ -5084,7 +5085,7 @@ bool GLCanvas3D::_init_undoredo_toolbar()
if (can_redo) { if (can_redo) {
std::string action; std::string action;
wxGetApp().plater()->undo_redo_topmost_string_getter(false, action); wxGetApp().plater()->undo_redo_topmost_string_getter(false, action);
new_additional_tooltip = (boost::format(_utf8(L("Next Redo action: %1%"))) % action).str(); new_additional_tooltip = format(_L("Next Redo action: %1%"), action);
} }
if (new_additional_tooltip != curr_additional_tooltip) { if (new_additional_tooltip != curr_additional_tooltip) {

View File

@ -5,7 +5,15 @@
#include "GUI_ObjectManipulation.hpp" #include "GUI_ObjectManipulation.hpp"
#include "GUI_Factories.hpp" #include "GUI_Factories.hpp"
#include "format.hpp" #include "format.hpp"
#include "I18N.hpp"
// Localization headers: include libslic3r version first so everything in this file
// uses the slic3r/GUI version (the macros will take precedence over the functions).
// Also, there is a check that the former is not included from slic3r module.
// This is the only place where we want to allow that, so define an override macro.
#define SLIC3R_ALLOW_LIBSLIC3R_I18N_IN_SLIC3R
#include "libslic3r/I18N.hpp"
#undef SLIC3R_ALLOW_LIBSLIC3R_I18N_IN_SLIC3R
#include "slic3r/GUI/I18N.hpp"
#include <algorithm> #include <algorithm>
#include <iterator> #include <iterator>
@ -44,7 +52,6 @@
#include "libslic3r/Utils.hpp" #include "libslic3r/Utils.hpp"
#include "libslic3r/Model.hpp" #include "libslic3r/Model.hpp"
#include "libslic3r/I18N.hpp"
#include "libslic3r/PresetBundle.hpp" #include "libslic3r/PresetBundle.hpp"
#include "libslic3r/Color.hpp" #include "libslic3r/Color.hpp"
@ -1981,7 +1988,7 @@ void GUI_App::import_model(wxWindow *parent, wxArrayString& input_files) const
void GUI_App::import_zip(wxWindow* parent, wxString& input_file) const void GUI_App::import_zip(wxWindow* parent, wxString& input_file) const
{ {
wxFileDialog dialog(parent ? parent : GetTopWindow(), wxFileDialog dialog(parent ? parent : GetTopWindow(),
_L("Choose ZIP file:"), _L("Choose ZIP file") + ":",
from_u8(app_config->get_last_dir()), "", from_u8(app_config->get_last_dir()), "",
file_wildcards(FT_ZIP), wxFD_OPEN | wxFD_FILE_MUST_EXIST); file_wildcards(FT_ZIP), wxFD_OPEN | wxFD_FILE_MUST_EXIST);
@ -2381,8 +2388,8 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
auto local_menu = new wxMenu(); auto local_menu = new wxMenu();
wxWindowID config_id_base = wxWindow::NewControlId(int(ConfigMenuCnt)); wxWindowID config_id_base = wxWindow::NewControlId(int(ConfigMenuCnt));
const auto config_wizard_name = _(ConfigWizard::name(true)); const wxString config_wizard_name = _(ConfigWizard::name(true));
const auto config_wizard_tooltip = from_u8((boost::format(_utf8(L("Run %s"))) % config_wizard_name).str()); const wxString config_wizard_tooltip = from_u8((boost::format(_u8L("Run %s")) % config_wizard_name).str());
// Cmd+, is standard on OS X - what about other operating systems? // Cmd+, is standard on OS X - what about other operating systems?
if (is_editor()) { if (is_editor()) {
local_menu->Append(config_id_base + ConfigMenuWizard, config_wizard_name + dots, config_wizard_tooltip); local_menu->Append(config_id_base + ConfigMenuWizard, config_wizard_name + dots, config_wizard_tooltip);
@ -2409,7 +2416,7 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
mode_menu = new wxMenu(); mode_menu = new wxMenu();
mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeSimple, _L("Simple"), _L("Simple View Mode")); mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeSimple, _L("Simple"), _L("Simple View Mode"));
// mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeAdvanced, _L("Advanced"), _L("Advanced View Mode")); // mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeAdvanced, _L("Advanced"), _L("Advanced View Mode"));
mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeAdvanced, _CTX(L_CONTEXT("Advanced", "Mode"), "Mode"), _L("Advanced View Mode")); mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeAdvanced, _CTX("Advanced", "Mode"), _L("Advanced View Mode"));
mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeExpert, _L("Expert"), _L("Expert View Mode")); mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeExpert, _L("Expert"), _L("Expert View Mode"));
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { if (get_mode() == comSimple) evt.Check(true); }, config_id_base + ConfigMenuModeSimple); Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { if (get_mode() == comSimple) evt.Check(true); }, config_id_base + ConfigMenuModeSimple);
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { if (get_mode() == comAdvanced) evt.Check(true); }, config_id_base + ConfigMenuModeAdvanced); Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { if (get_mode() == comAdvanced) evt.Check(true); }, config_id_base + ConfigMenuModeAdvanced);
@ -3433,7 +3440,7 @@ void GUI_App::app_updater(bool from_user)
} }
app_data.target_path =dwnld_dlg.get_download_path(); app_data.target_path =dwnld_dlg.get_download_path();
// start download // start download
this->plater_->get_notification_manager()->push_download_progress_notification(GUI::format(_utf8("Downloading %1%"), app_data.target_path.filename().string()), std::bind(&AppUpdater::cancel_callback, this->m_app_updater.get())); this->plater_->get_notification_manager()->push_download_progress_notification(GUI::format(_L("Downloading %1%"), app_data.target_path.filename().string()), std::bind(&AppUpdater::cancel_callback, this->m_app_updater.get()));
app_data.start_after = dwnld_dlg.run_after_download(); app_data.start_after = dwnld_dlg.run_after_download();
m_app_updater->set_app_data(std::move(app_data)); m_app_updater->set_app_data(std::move(app_data));
m_app_updater->sync_download(); m_app_updater->sync_download();
@ -3461,7 +3468,7 @@ void GUI_App::start_download(std::string url)
//lets always init so if the download dest folder was changed, new dest is used //lets always init so if the download dest folder was changed, new dest is used
boost::filesystem::path dest_folder(app_config->get("url_downloader_dest")); boost::filesystem::path dest_folder(app_config->get("url_downloader_dest"));
if (dest_folder.empty() || !boost::filesystem::is_directory(dest_folder)) { if (dest_folder.empty() || !boost::filesystem::is_directory(dest_folder)) {
std::string msg = _utf8("Could not start URL download. Destination folder is not set. Please choose destination folder in Configuration Wizard."); std::string msg = _u8L("Could not start URL download. Destination folder is not set. Please choose destination folder in Configuration Wizard.");
BOOST_LOG_TRIVIAL(error) << msg; BOOST_LOG_TRIVIAL(error) << msg;
show_error(nullptr, msg); show_error(nullptr, msg);
return; return;

View File

@ -411,7 +411,7 @@ static void create_freq_settings_popupmenu(wxMenu* menu, const bool is_object_se
if (is_improper_category(category.first, extruders_cnt)) if (is_improper_category(category.first, extruders_cnt))
continue; continue;
append_menu_item(menu, wxID_ANY, from_u8((boost::format(_utf8(L("Quick Add Settings (%s)"))) % _(it.first)).str()), "", append_menu_item(menu, wxID_ANY, format_wxstr(_L("Quick Add Settings (%s)"), _(it.first)), "",
[menu, item, is_object_settings, bundle](wxCommandEvent& event) { [menu, item, is_object_settings, bundle](wxCommandEvent& event) {
wxString category_name = menu->GetLabel(event.GetId()); wxString category_name = menu->GetLabel(event.GetId());
std::vector<std::string> options; std::vector<std::string> options;
@ -622,13 +622,13 @@ wxMenuItem* MenuFactory::append_menu_item_settings(wxMenu* menu_)
#if 0 #if 0
for (auto& it : m_freq_settings_fff) for (auto& it : m_freq_settings_fff)
{ {
settings_id = menu->FindItem(from_u8((boost::format(_utf8(L("Quick Add Settings (%s)"))) % _(it.first)).str())); settings_id = menu->FindItem(format_wxstr(_L("Quick Add Settings (%s)"), _(it.first)));
if (settings_id != wxNOT_FOUND) if (settings_id != wxNOT_FOUND)
menu->Destroy(settings_id); menu->Destroy(settings_id);
} }
for (auto& it : m_freq_settings_sla) for (auto& it : m_freq_settings_sla)
{ {
settings_id = menu->FindItem(from_u8((boost::format(_utf8(L("Quick Add Settings (%s)"))) % _(it.first)).str())); settings_id = menu->FindItem(format_wxstr(_L("Quick Add Settings (%s)"), _(it.first)));
if (settings_id != wxNOT_FOUND) if (settings_id != wxNOT_FOUND)
menu->Destroy(settings_id); menu->Destroy(settings_id);
} }
@ -1000,7 +1000,7 @@ void MenuFactory::append_menu_item_edit_text(wxMenu *menu)
std::string icon = ""; std::string icon = "";
append_menu_item( append_menu_item(
menu, wxID_ANY, name, description, menu, wxID_ANY, name, description,
[can_edit_text](wxCommandEvent &) { [](wxCommandEvent &) {
plater()->canvas3D()->get_gizmos_manager().open_gizmo(GLGizmosManager::Emboss); plater()->canvas3D()->get_gizmos_manager().open_gizmo(GLGizmosManager::Emboss);
}, },
icon, nullptr, can_edit_text, m_parent); icon, nullptr, can_edit_text, m_parent);

View File

@ -420,7 +420,7 @@ MeshErrorsInfo ObjectList::get_mesh_errors_info(const int obj_idx, const int vol
const ModelObject* object = (*m_objects)[obj_idx]; const ModelObject* object = (*m_objects)[obj_idx];
if (vol_idx != -1 && vol_idx >= int(object->volumes.size())) { if (vol_idx != -1 && vol_idx >= int(object->volumes.size())) {
if (sidebar_info) if (sidebar_info)
*sidebar_info = _L("Wrong volume index "); *sidebar_info = _L("Wrong volume index") + " ";
return { {}, {} }; // hide tooltip return { {}, {} }; // hide tooltip
} }
@ -2063,9 +2063,8 @@ bool ObjectList::del_from_cut_object(bool is_cut_connector, bool is_model_part/*
InfoDialog dialog(wxGetApp().plater(), title, InfoDialog dialog(wxGetApp().plater(), title,
_L("This action will break a cut information.\n" _L("This action will break a cut information.\n"
"After that PrusaSlicer can't guarantee model consistency.\n" "After that PrusaSlicer can't guarantee model consistency.") + "\n\n" +
"\n" _L("To manipulate with solid parts or negative volumes you have to invalidate cut infornation first." + msg_end ),
"To manipulate with solid parts or negative volumes you have to invalidate cut infornation first." + msg_end ),
false, buttons_style | wxCANCEL_DEFAULT | wxICON_WARNING); false, buttons_style | wxCANCEL_DEFAULT | wxICON_WARNING);
dialog.SetButtonLabel(wxID_YES, _L("Invalidate cut info")); dialog.SetButtonLabel(wxID_YES, _L("Invalidate cut info"));

View File

@ -272,11 +272,10 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
// We will add a button to toggle mirroring to each axis: // We will add a button to toggle mirroring to each axis:
auto btn = new ScalableButton(parent, wxID_ANY, "mirroring_off", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER | wxTRANSPARENT_WINDOW); auto btn = new ScalableButton(parent, wxID_ANY, "mirroring_off", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER | wxTRANSPARENT_WINDOW);
#if ENABLE_WORLD_COORDINATE #if ENABLE_WORLD_COORDINATE
btn->SetToolTip(_L("Mirror along") + wxString::Format(_L(" %c "), (int)label) + _L("axis")); btn->SetToolTip(format_wxstr(_L("Mirror along %1% axis"), label));
m_mirror_buttons[axis_idx] = btn; m_mirror_buttons[axis_idx] = btn;
#else #else
btn->SetToolTip(wxString::Format(_L("Toggle %c axis mirroring"), (int)label)); btn->SetToolTip(format_wxstr(_L("Toggle %1% axis mirroring"), label));
btn->SetBitmapDisabled_(m_mirror_bitmap_hidden); btn->SetBitmapDisabled_(m_mirror_bitmap_hidden);
m_mirror_buttons[axis_idx].first = btn; m_mirror_buttons[axis_idx].first = btn;

View File

@ -102,7 +102,7 @@ bool ObjectSettings::update_settings_list()
btn->SetBitmapCurrent(m_bmp_delete_focus.bmp()); btn->SetBitmapCurrent(m_bmp_delete_focus.bmp());
btn->Bind(wxEVT_BUTTON, [opt_key, config, this](wxEvent &event) { btn->Bind(wxEVT_BUTTON, [opt_key, config, this](wxEvent &event) {
wxGetApp().plater()->take_snapshot(from_u8((boost::format(_utf8(L("Delete Option %s"))) % opt_key).str())); wxGetApp().plater()->take_snapshot(format_wxstr(_L("Delete Option %s"), opt_key));
config->erase(opt_key); config->erase(opt_key);
wxGetApp().obj_list()->changed_object(); wxGetApp().obj_list()->changed_object();
wxTheApp->CallAfter([this]() { wxTheApp->CallAfter([this]() {
@ -151,7 +151,7 @@ bool ObjectSettings::update_settings_list()
for (auto& opt : cat.second) for (auto& opt : cat.second)
optgroup->get_field(opt)->m_on_change = [optgroup](const std::string& opt_id, const boost::any& value) { optgroup->get_field(opt)->m_on_change = [optgroup](const std::string& opt_id, const boost::any& value) {
// first of all take a snapshot and then change value in configuration // first of all take a snapshot and then change value in configuration
wxGetApp().plater()->take_snapshot(from_u8((boost::format(_utf8(L("Change Option %s"))) % opt_id).str())); wxGetApp().plater()->take_snapshot(format_wxstr(_L("Change Option %s"), opt_id));
optgroup->on_change_OG(opt_id, value); optgroup->on_change_OG(opt_id, value);
}; };

View File

@ -149,15 +149,21 @@ void GLGizmoBase::Grabber::render(float size, const ColorRGBA& render_color)
GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
: m_parent(parent) : m_parent(parent)
, m_group_id(-1) , m_group_id(-1)
, m_state(Off) , m_state(Off)
, m_shortcut_key(NO_SHORTCUT_KEY_VALUE) , m_shortcut_key(NO_SHORTCUT_KEY_VALUE)
, m_icon_filename(icon_filename) , m_icon_filename(icon_filename)
, m_sprite_id(sprite_id) , m_sprite_id(sprite_id)
, m_imgui(wxGetApp().imgui()) , m_imgui(wxGetApp().imgui())
{ {
} }
std::string GLGizmoBase::get_action_snapshot_name() const
{
return _u8L("Gizmo action");
}
void GLGizmoBase::set_hover_id(int id) void GLGizmoBase::set_hover_id(int id)
{ {
// do not change hover id during dragging // do not change hover id during dragging
@ -351,12 +357,12 @@ void GLGizmoBase::render_input_window(float x, float y, float bottom_limit)
std::string GLGizmoBase::get_name(bool include_shortcut) const std::string GLGizmoBase::get_name(bool include_shortcut) const
{ {
std::string out = on_get_name(); std::string out = on_get_name();
if (!include_shortcut) return out; if (!include_shortcut) return out;
int key = get_shortcut_key(); int key = get_shortcut_key();
assert(key==NO_SHORTCUT_KEY_VALUE || (key >= WXK_CONTROL_A && key <= WXK_CONTROL_Z)); assert(key==NO_SHORTCUT_KEY_VALUE || (key >= WXK_CONTROL_A && key <= WXK_CONTROL_Z));
out += std::string(" [") + char(int('A') + key - int(WXK_CONTROL_A)) + "]"; out += std::string(" [") + char(int('A') + key - int(WXK_CONTROL_A)) + "]";
return out; return out;
} }

View File

@ -4,7 +4,6 @@
#include "libslic3r/Point.hpp" #include "libslic3r/Point.hpp"
#include "libslic3r/Color.hpp" #include "libslic3r/Color.hpp"
#include "slic3r/GUI/I18N.hpp"
#include "slic3r/GUI/GLModel.hpp" #include "slic3r/GUI/GLModel.hpp"
#include "slic3r/GUI/MeshUtils.hpp" #include "slic3r/GUI/MeshUtils.hpp"
#include "slic3r/GUI/SceneRaycaster.hpp" #include "slic3r/GUI/SceneRaycaster.hpp"
@ -150,7 +149,7 @@ public:
virtual bool wants_enter_leave_snapshots() const { return false; } virtual bool wants_enter_leave_snapshots() const { return false; }
virtual std::string get_gizmo_entering_text() const { assert(false); return ""; } virtual std::string get_gizmo_entering_text() const { assert(false); return ""; }
virtual std::string get_gizmo_leaving_text() const { assert(false); return ""; } virtual std::string get_gizmo_leaving_text() const { assert(false); return ""; }
virtual std::string get_action_snapshot_name() { return _u8L("Gizmo action"); } virtual std::string get_action_snapshot_name() const;
void set_common_data_pool(CommonGizmosDataPool* ptr) { m_c = ptr; } void set_common_data_pool(CommonGizmosDataPool* ptr) { m_c = ptr; }
unsigned int get_sprite_id() const { return m_sprite_id; } unsigned int get_sprite_id() const { return m_sprite_id; }

View File

@ -1,4 +1,3 @@
// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro.
#include "GLGizmoCut.hpp" #include "GLGizmoCut.hpp"
#include "slic3r/GUI/GLCanvas3D.hpp" #include "slic3r/GUI/GLCanvas3D.hpp"
@ -183,9 +182,9 @@ GLGizmoCut3D::GLGizmoCut3D(GLCanvas3D& parent, const std::string& icon_filename,
, m_connector_style (size_t(CutConnectorStyle::Prism)) , m_connector_style (size_t(CutConnectorStyle::Prism))
, m_connector_shape_id (size_t(CutConnectorShape::Circle)) , m_connector_shape_id (size_t(CutConnectorShape::Circle))
{ {
m_modes = { _u8L("Planar")//, _u8L("Grid") // m_modes = { _u8L("Planar"), _u8L("Grid")
// , _u8L("Radial"), _u8L("Modular") // , _u8L("Radial"), _u8L("Modular")
}; // };
m_connector_modes = { _u8L("Auto"), _u8L("Manual") }; m_connector_modes = { _u8L("Auto"), _u8L("Manual") };
@ -232,7 +231,7 @@ std::string GLGizmoCut3D::get_tooltip() const
std::string tooltip; std::string tooltip;
if (m_hover_id == Z || (m_dragging && m_hover_id == CutPlane)) { if (m_hover_id == Z || (m_dragging && m_hover_id == CutPlane)) {
double koef = m_imperial_units ? ObjectManipulation::mm_to_in : 1.0; double koef = m_imperial_units ? ObjectManipulation::mm_to_in : 1.0;
std::string unit_str = " " + (m_imperial_units ? _u8L("inch") : _u8L("mm")); std::string unit_str = " " + (m_imperial_units ? _u8L("in") : _u8L("mm"));
const BoundingBoxf3& tbb = m_transformed_bounding_box; const BoundingBoxf3& tbb = m_transformed_bounding_box;
const std::string name = m_keep_as_parts ? _u8L("Part") : _u8L("Object"); const std::string name = m_keep_as_parts ? _u8L("Part") : _u8L("Object");
@ -1682,7 +1681,7 @@ void GLGizmoCut3D::render_cut_plane_input_window(CutConnectors &connectors)
render_build_size(); render_build_size();
ImGui::AlignTextToFramePadding(); ImGui::AlignTextToFramePadding();
ImGuiWrapper::text(_L("Cut position: ")); ImGuiWrapper::text(_L("Cut position") + ": ");
ImGui::SameLine(); ImGui::SameLine();
render_move_center_input(Z); render_move_center_input(Z);
ImGui::SameLine(); ImGui::SameLine();
@ -1789,9 +1788,11 @@ void GLGizmoCut3D::render_cut_plane_input_window(CutConnectors &connectors)
ImGuiWrapper::text(_L("Cut to") + ":"); ImGuiWrapper::text(_L("Cut to") + ":");
add_horizontal_scaled_interval(1.2f); add_horizontal_scaled_interval(1.2f);
// TRN CutGizmo: RadioButton Cut to ...
if (m_imgui->radio_button(_L("Objects"), !m_keep_as_parts)) if (m_imgui->radio_button(_L("Objects"), !m_keep_as_parts))
m_keep_as_parts = false; m_keep_as_parts = false;
ImGui::SameLine(); ImGui::SameLine();
// TRN CutGizmo: RadioButton Cut to ...
if (m_imgui->radio_button(_L("Parts"), m_keep_as_parts)) if (m_imgui->radio_button(_L("Parts"), m_keep_as_parts))
m_keep_as_parts = true; m_keep_as_parts = true;

View File

@ -4,6 +4,7 @@
#include "GLGizmoBase.hpp" #include "GLGizmoBase.hpp"
#include "slic3r/GUI/GLSelectionRectangle.hpp" #include "slic3r/GUI/GLSelectionRectangle.hpp"
#include "slic3r/GUI/GLModel.hpp" #include "slic3r/GUI/GLModel.hpp"
#include "slic3r/GUI/I18N.hpp"
#include "libslic3r/TriangleMesh.hpp" #include "libslic3r/TriangleMesh.hpp"
#include "libslic3r/Model.hpp" #include "libslic3r/Model.hpp"
#include "imgui/imgui.h" #include "imgui/imgui.h"
@ -150,7 +151,7 @@ class GLGizmoCut3D : public GLGizmoBase
, Manual , Manual
}; };
std::vector<std::string> m_modes; // std::vector<std::string> m_modes;
size_t m_mode{ size_t(CutMode::cutPlanar) }; size_t m_mode{ size_t(CutMode::cutPlanar) };
std::vector<std::string> m_connector_modes; std::vector<std::string> m_connector_modes;
@ -253,7 +254,7 @@ protected:
bool wants_enter_leave_snapshots() const override { return true; } bool wants_enter_leave_snapshots() const override { return true; }
std::string get_gizmo_entering_text() const override { return _u8L("Entering Cut gizmo"); } std::string get_gizmo_entering_text() const override { return _u8L("Entering Cut gizmo"); }
std::string get_gizmo_leaving_text() const override { return _u8L("Leaving Cut gizmo"); } std::string get_gizmo_leaving_text() const override { return _u8L("Leaving Cut gizmo"); }
std::string get_action_snapshot_name() override { return _u8L("Cut gizmo editing"); } std::string get_action_snapshot_name() const override { return _u8L("Cut gizmo editing"); }
void data_changed() override; void data_changed() override;

View File

@ -1329,6 +1329,7 @@ void GLGizmoEmboss::draw_text_input()
warning_tool_tip += "\n"; warning_tool_tip += "\n";
warning_tool_tip += t; warning_tool_tip += t;
}; };
if (priv::is_text_empty(m_text)) if (priv::is_text_empty(m_text))
append_warning(_u8L("Embossed text can NOT contain only white spaces.")); append_warning(_u8L("Embossed text can NOT contain only white spaces."));
if (m_text_contain_unknown_glyph) if (m_text_contain_unknown_glyph)
@ -1650,9 +1651,9 @@ void GLGizmoEmboss::draw_font_preview(FaceName& face, bool is_visible)
// Not finished preview // Not finished preview
if (is_visible) { if (is_visible) {
// when not canceled still loading // when not canceled still loading
state_text = (face.cancel->load())? state_text = std::string(" ") + (face.cancel->load() ?
_u8L(" No symbol"): _u8L("No symbol") :
_u8L(" ... Loading"); (dots.ToStdString() + _u8L("Loading")));
} else { } else {
// not finished and not visible cancel job // not finished and not visible cancel job
face.is_created = nullptr; face.is_created = nullptr;
@ -1702,7 +1703,7 @@ void GLGizmoEmboss::draw_font_preview(FaceName& face, bool is_visible)
queue_job(worker, std::move(job)); queue_job(worker, std::move(job));
} else { } else {
// cant start new thread at this moment so wait in queue // cant start new thread at this moment so wait in queue
state_text = _u8L(" ... In queue"); state_text = " " + dots.ToStdString() + " " + _u8L("Queue");
} }
if (!state_text.empty()) { if (!state_text.empty()) {
@ -1936,7 +1937,7 @@ void GLGizmoEmboss::draw_font_list()
process(); process();
} }
} else if (ImGui::IsItemHovered()) } else if (ImGui::IsItemHovered())
ImGui::SetTooltip("%s", _u8L("add file with font(.ttf, .ttc)").c_str()); ImGui::SetTooltip("Add file with font(.ttf, .ttc)");
#endif // ALLOW_ADD_FONT_BY_FILE #endif // ALLOW_ADD_FONT_BY_FILE
#ifdef ALLOW_ADD_FONT_BY_OS_SELECTOR #ifdef ALLOW_ADD_FONT_BY_OS_SELECTOR
@ -1946,7 +1947,7 @@ void GLGizmoEmboss::draw_font_list()
process(); process();
} }
} else if (ImGui::IsItemHovered()) } else if (ImGui::IsItemHovered())
ImGui::SetTooltip("%s", _u8L("Open dialog for choose from fonts.").c_str()); ImGui::SetTooltip("Open dialog for choose from fonts.");
#endif // ALLOW_ADD_FONT_BY_OS_SELECTOR #endif // ALLOW_ADD_FONT_BY_OS_SELECTOR
} }
@ -2031,7 +2032,7 @@ void GLGizmoEmboss::draw_model_type()
void GLGizmoEmboss::draw_style_rename_popup() { void GLGizmoEmboss::draw_style_rename_popup() {
std::string& new_name = m_style_manager.get_style().name; std::string& new_name = m_style_manager.get_style().name;
const std::string &old_name = m_style_manager.get_stored_style()->name; const std::string &old_name = m_style_manager.get_stored_style()->name;
std::string text_in_popup = GUI::format(_L("Rename style(%1%) for embossing text: "), old_name); std::string text_in_popup = GUI::format(_L("Rename style(%1%) for embossing text"), old_name) + ": ";
ImGui::Text("%s", text_in_popup.c_str()); ImGui::Text("%s", text_in_popup.c_str());
bool is_unique = true; bool is_unique = true;
@ -2054,9 +2055,9 @@ void GLGizmoEmboss::draw_style_rename_popup() {
bool store = false; bool store = false;
ImGuiInputTextFlags flags = ImGuiInputTextFlags_EnterReturnsTrue; ImGuiInputTextFlags flags = ImGuiInputTextFlags_EnterReturnsTrue;
if (ImGui::InputText("##rename style", &new_name, flags) && allow_change) store = true; if (ImGui::InputText("##rename style", &new_name, flags) && allow_change) store = true;
if (m_imgui->button(_L("ok"), ImVec2(0.f, 0.f), allow_change)) store = true; if (m_imgui->button(_L("OK"), ImVec2(0.f, 0.f), allow_change)) store = true;
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button(_u8L("cancel").c_str())) { if (ImGui::Button(_u8L("Cancel").c_str())) {
new_name = old_name; new_name = old_name;
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
@ -2117,7 +2118,7 @@ void GLGizmoEmboss::draw_style_save_button(bool is_modified)
} }
void GLGizmoEmboss::draw_style_save_as_popup() { void GLGizmoEmboss::draw_style_save_as_popup() {
ImGui::Text("%s", _u8L("New name of style: ").c_str()); ImGui::Text("%s", (_u8L("New name of style") +": ").c_str());
// use name inside of volume configuration as temporary new name // use name inside of volume configuration as temporary new name
std::string &new_name = m_volume->text_configuration->style.name; std::string &new_name = m_volume->text_configuration->style.name;
@ -2141,11 +2142,11 @@ void GLGizmoEmboss::draw_style_save_as_popup() {
if (ImGui::InputText("##save as style", &new_name, flags)) if (ImGui::InputText("##save as style", &new_name, flags))
save_style = true; save_style = true;
if (m_imgui->button(_L("ok"), ImVec2(0.f, 0.f), allow_change)) if (m_imgui->button(_L("OK"), ImVec2(0.f, 0.f), allow_change))
save_style = true; save_style = true;
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button(_u8L("cancel").c_str())){ if (ImGui::Button(_u8L("Cancel").c_str())){
// write original name to volume TextConfiguration // write original name to volume TextConfiguration
new_name = m_style_manager.get_style().name; new_name = m_style_manager.get_style().name;
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
@ -2388,7 +2389,7 @@ void GLGizmoEmboss::draw_style_list() {
process(); process();
} else { } else {
wxString title = _L("Not valid style."); wxString title = _L("Not valid style.");
wxString message = GUI::format_wxstr(_L("Style '%1%' can't be used and will be removed from list."), style.name); wxString message = GUI::format_wxstr(_L("Style '%1%' can't be used and will be removed from a list."), style.name);
MessageDialog not_loaded_style_message(nullptr, message, title, wxOK); MessageDialog not_loaded_style_message(nullptr, message, title, wxOK);
not_loaded_style_message.ShowModal(); not_loaded_style_message.ShowModal();
m_style_manager.erase(*selected_style_index); m_style_manager.erase(*selected_style_index);
@ -2840,7 +2841,7 @@ void GLGizmoEmboss::draw_advanced()
process(); process();
} }
m_imgui->disabled_end(); // !can_use_surface m_imgui->disabled_end(); // !can_use_surface
// TRN EmbossGizmo: font units
std::string units = _u8L("font points"); std::string units = _u8L("font points");
std::string units_fmt = "%.0f " + units; std::string units_fmt = "%.0f " + units;
@ -3111,9 +3112,9 @@ bool GLGizmoEmboss::choose_font_by_wxdialog()
(!use_deserialized_font && !m_style_manager.load_style(emboss_style, wx_font))) { (!use_deserialized_font && !m_style_manager.load_style(emboss_style, wx_font))) {
m_style_manager.erase(font_index); m_style_manager.erase(font_index);
wxString message = GUI::format_wxstr( wxString message = GUI::format_wxstr(
_L("Font '%1%' can't be used. Please select another."), "Font '%1%' can't be used. Please select another.",
emboss_style.name); emboss_style.name);
wxString title = _L("Selected font is NOT True-type."); wxString title = "Selected font is NOT True-type.";
MessageDialog not_loaded_font_message(nullptr, message, title, wxOK); MessageDialog not_loaded_font_message(nullptr, message, title, wxOK);
not_loaded_font_message.ShowModal(); not_loaded_font_message.ShowModal();
return choose_font_by_wxdialog(); return choose_font_by_wxdialog();
@ -3150,7 +3151,7 @@ bool GLGizmoEmboss::choose_true_type_file()
wxArrayString input_files; wxArrayString input_files;
wxString fontDir = wxEmptyString; wxString fontDir = wxEmptyString;
wxString selectedFile = wxEmptyString; wxString selectedFile = wxEmptyString;
wxFileDialog dialog(nullptr, _L("Choose one or more files (TTF, TTC):"), wxFileDialog dialog(nullptr, "Choose one or more files (TTF, TTC):",
fontDir, selectedFile, file_wildcards(FT_FONTS), fontDir, selectedFile, file_wildcards(FT_FONTS),
wxFD_OPEN | wxFD_FILE_MUST_EXIST); wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if (dialog.ShowModal() == wxID_OK) dialog.GetPaths(input_files); if (dialog.ShowModal() == wxID_OK) dialog.GetPaths(input_files);
@ -3178,7 +3179,7 @@ bool GLGizmoEmboss::choose_svg_file()
wxArrayString input_files; wxArrayString input_files;
wxString fontDir = wxEmptyString; wxString fontDir = wxEmptyString;
wxString selectedFile = wxEmptyString; wxString selectedFile = wxEmptyString;
wxFileDialog dialog(nullptr, _L("Choose SVG file:"), fontDir, wxFileDialog dialog(nullptr, _L("Choose SVG file")+":", fontDir,
selectedFile, file_wildcards(FT_SVG), selectedFile, file_wildcards(FT_SVG),
wxFD_OPEN | wxFD_FILE_MUST_EXIST); wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if (dialog.ShowModal() == wxID_OK) dialog.GetPaths(input_files); if (dialog.ShowModal() == wxID_OK) dialog.GetPaths(input_files);
@ -3226,7 +3227,7 @@ void GLGizmoEmboss::create_notification_not_valid_font(
} }
const std::string &face_name = face_name_opt.value_or(face_name_by_wx.value_or(es.path)); const std::string &face_name = face_name_opt.value_or(face_name_by_wx.value_or(es.path));
std::string text = std::string text =
GUI::format(_L("Can't load exactly same font(\"%1%\"), " GUI::format(_L("Can't load exactly same font(\"%1%\"). "
"Aplication selected a similar one(\"%2%\"). " "Aplication selected a similar one(\"%2%\"). "
"You have to specify font for enable edit text."), "You have to specify font for enable edit text."),
face_name_3mf, face_name); face_name_3mf, face_name);

View File

@ -1,12 +1,11 @@
#ifndef slic3r_GLGizmoEmboss_hpp_ #ifndef slic3r_GLGizmoEmboss_hpp_
#define slic3r_GLGizmoEmboss_hpp_ #define slic3r_GLGizmoEmboss_hpp_
// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code,
// which overrides our localization "L" macro.
#include "GLGizmoBase.hpp" #include "GLGizmoBase.hpp"
#include "GLGizmoRotate.hpp" #include "GLGizmoRotate.hpp"
#include "slic3r/GUI/IconManager.hpp" #include "slic3r/GUI/IconManager.hpp"
#include "slic3r/GUI/SurfaceDrag.hpp" #include "slic3r/GUI/SurfaceDrag.hpp"
#include "slic3r/GUI/I18N.hpp"
#include "slic3r/Utils/RaycastManager.hpp" #include "slic3r/Utils/RaycastManager.hpp"
#include "slic3r/Utils/EmbossStyleManager.hpp" #include "slic3r/Utils/EmbossStyleManager.hpp"
@ -76,7 +75,7 @@ protected:
bool wants_enter_leave_snapshots() const override { return true; } bool wants_enter_leave_snapshots() const override { return true; }
std::string get_gizmo_entering_text() const override { return _u8L("Enter emboss gizmo"); } std::string get_gizmo_entering_text() const override { return _u8L("Enter emboss gizmo"); }
std::string get_gizmo_leaving_text() const override { return _u8L("Leave emboss gizmo"); } std::string get_gizmo_leaving_text() const override { return _u8L("Leave emboss gizmo"); }
std::string get_action_snapshot_name() override { return _u8L("Embossing actions"); } std::string get_action_snapshot_name() const override { return _u8L("Embossing actions"); }
private: private:
static EmbossStyles create_default_styles(); static EmbossStyles create_default_styles();
// localized default text // localized default text

View File

@ -44,7 +44,8 @@ bool GLGizmoFdmSupports::on_init()
m_shortcut_key = WXK_CONTROL_L; m_shortcut_key = WXK_CONTROL_L;
m_desc["autopaint"] = _L("Automatic painting"); m_desc["autopaint"] = _L("Automatic painting");
m_desc["painting"] = _L("painting..."); // TRN GizmoFdmSupports : message line during the waiting for autogenerated supports
m_desc["painting"] = _L("painting") + dots;
m_desc["clipping_of_view"] = _L("Clipping of view") + ": "; m_desc["clipping_of_view"] = _L("Clipping of view") + ": ";
m_desc["reset_direction"] = _L("Reset direction"); m_desc["reset_direction"] = _L("Reset direction");
m_desc["cursor_size"] = _L("Brush size") + ": "; m_desc["cursor_size"] = _L("Brush size") + ": ";

View File

@ -3,6 +3,8 @@
#include "GLGizmoPainterBase.hpp" #include "GLGizmoPainterBase.hpp"
#include "slic3r/GUI/I18N.hpp"
namespace Slic3r::GUI { namespace Slic3r::GUI {
class GLGizmoFdmSupports : public GLGizmoPainterBase class GLGizmoFdmSupports : public GLGizmoPainterBase
@ -21,7 +23,7 @@ protected:
std::string get_gizmo_entering_text() const override { return _u8L("Entering Paint-on supports"); } std::string get_gizmo_entering_text() const override { return _u8L("Entering Paint-on supports"); }
std::string get_gizmo_leaving_text() const override { return _u8L("Leaving Paint-on supports"); } std::string get_gizmo_leaving_text() const override { return _u8L("Leaving Paint-on supports"); }
std::string get_action_snapshot_name() override { return _u8L("Paint-on supports editing"); } std::string get_action_snapshot_name() const override { return _u8L("Paint-on supports editing"); }
private: private:

View File

@ -1,4 +1,3 @@
// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro.
#include "GLGizmoFlatten.hpp" #include "GLGizmoFlatten.hpp"
#include "slic3r/GUI/GLCanvas3D.hpp" #include "slic3r/GUI/GLCanvas3D.hpp"
#include "slic3r/GUI/GUI_App.hpp" #include "slic3r/GUI/GUI_App.hpp"

View File

@ -1,4 +1,3 @@
// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro.
#include "GLGizmoMeasure.hpp" #include "GLGizmoMeasure.hpp"
#include "slic3r/GUI/GLCanvas3D.hpp" #include "slic3r/GUI/GLCanvas3D.hpp"
#include "slic3r/GUI/GUI_App.hpp" #include "slic3r/GUI/GUI_App.hpp"
@ -1538,7 +1537,7 @@ void GLGizmoMeasure::render_dimensioning()
m_imgui->set_next_window_pos(label_position_ss.x(), viewport[3] - label_position_ss.y(), ImGuiCond_Always, 0.0f, 1.0f); m_imgui->set_next_window_pos(label_position_ss.x(), viewport[3] - label_position_ss.y(), ImGuiCond_Always, 0.0f, 1.0f);
m_imgui->set_next_window_bg_alpha(0.0f); m_imgui->set_next_window_bg_alpha(0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
m_imgui->begin(_L("##angle"), ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); m_imgui->begin(wxString("##angle"), ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove);
ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindow()); ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindow());
ImGui::AlignTextToFramePadding(); ImGui::AlignTextToFramePadding();
ImDrawList* draw_list = ImGui::GetWindowDrawList(); ImDrawList* draw_list = ImGui::GetWindowDrawList();
@ -1737,7 +1736,7 @@ void GLGizmoMeasure::render_debug_dialog()
add_strings_row_to_table(*m_imgui, "m_pt3", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(*extra_point), ImGui::GetStyleColorVec4(ImGuiCol_Text)); add_strings_row_to_table(*m_imgui, "m_pt3", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(*extra_point), ImGui::GetStyleColorVec4(ImGuiCol_Text));
}; };
m_imgui->begin(_L("Measure tool debug"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); m_imgui->begin("Measure tool debug", ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
if (ImGui::BeginTable("Mode", 2)) { if (ImGui::BeginTable("Mode", 2)) {
std::string txt; std::string txt;
switch (m_mode) switch (m_mode)

View File

@ -5,6 +5,7 @@
#include "slic3r/GUI/GLModel.hpp" #include "slic3r/GUI/GLModel.hpp"
#include "slic3r/GUI/GUI_Utils.hpp" #include "slic3r/GUI/GUI_Utils.hpp"
#include "slic3r/GUI/MeshUtils.hpp" #include "slic3r/GUI/MeshUtils.hpp"
#include "slic3r/GUI/I18N.hpp"
#include "libslic3r/Measure.hpp" #include "libslic3r/Measure.hpp"
#include "libslic3r/Model.hpp" #include "libslic3r/Model.hpp"
@ -162,7 +163,7 @@ public:
bool wants_enter_leave_snapshots() const override { return true; } bool wants_enter_leave_snapshots() const override { return true; }
std::string get_gizmo_entering_text() const override { return _u8L("Entering Measure gizmo"); } std::string get_gizmo_entering_text() const override { return _u8L("Entering Measure gizmo"); }
std::string get_gizmo_leaving_text() const override { return _u8L("Leaving Measure gizmo"); } std::string get_gizmo_leaving_text() const override { return _u8L("Leaving Measure gizmo"); }
std::string get_action_snapshot_name() override { return _u8L("Measure gizmo editing"); } std::string get_action_snapshot_name() const override { return _u8L("Measure gizmo editing"); }
protected: protected:
bool on_init() override; bool on_init() override;

View File

@ -3,6 +3,8 @@
#include "GLGizmoPainterBase.hpp" #include "GLGizmoPainterBase.hpp"
#include "slic3r/GUI/I18N.hpp"
namespace Slic3r::GUI { namespace Slic3r::GUI {
class GLMmSegmentationGizmo3DScene class GLMmSegmentationGizmo3DScene
@ -117,7 +119,7 @@ protected:
std::string get_gizmo_entering_text() const override { return _u8L("Entering Multimaterial painting"); } std::string get_gizmo_entering_text() const override { return _u8L("Entering Multimaterial painting"); }
std::string get_gizmo_leaving_text() const override { return _u8L("Leaving Multimaterial painting"); } std::string get_gizmo_leaving_text() const override { return _u8L("Leaving Multimaterial painting"); }
std::string get_action_snapshot_name() override { return _u8L("Multimaterial painting editing"); } std::string get_action_snapshot_name() const override { return _u8L("Multimaterial painting editing"); }
size_t m_first_selected_extruder_idx = 0; size_t m_first_selected_extruder_idx = 0;
size_t m_second_selected_extruder_idx = 1; size_t m_second_selected_extruder_idx = 1;

View File

@ -1,4 +1,3 @@
// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro.
#include "GLGizmoMove.hpp" #include "GLGizmoMove.hpp"
#include "slic3r/GUI/GLCanvas3D.hpp" #include "slic3r/GUI/GLCanvas3D.hpp"
#include "slic3r/GUI/GUI_App.hpp" #include "slic3r/GUI/GUI_App.hpp"

View File

@ -1,4 +1,3 @@
// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro.
#include "GLGizmoPainterBase.hpp" #include "GLGizmoPainterBase.hpp"
#include "slic3r/GUI/GLCanvas3D.hpp" #include "slic3r/GUI/GLCanvas3D.hpp"
#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp" #include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp"

View File

@ -1,4 +1,3 @@
// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro.
#include "GLGizmoRotate.hpp" #include "GLGizmoRotate.hpp"
#include "slic3r/GUI/GLCanvas3D.hpp" #include "slic3r/GUI/GLCanvas3D.hpp"
#include "slic3r/GUI/ImGuiWrapper.hpp" #include "slic3r/GUI/ImGuiWrapper.hpp"

View File

@ -1,4 +1,3 @@
// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro.
#include "GLGizmoScale.hpp" #include "GLGizmoScale.hpp"
#include "slic3r/GUI/GLCanvas3D.hpp" #include "slic3r/GUI/GLCanvas3D.hpp"
#include "slic3r/GUI/GUI_App.hpp" #include "slic3r/GUI/GUI_App.hpp"

View File

@ -3,6 +3,8 @@
#include "GLGizmoPainterBase.hpp" #include "GLGizmoPainterBase.hpp"
#include "slic3r/GUI/I18N.hpp"
namespace Slic3r::GUI { namespace Slic3r::GUI {
class GLGizmoSeam : public GLGizmoPainterBase class GLGizmoSeam : public GLGizmoPainterBase
@ -22,7 +24,7 @@ protected:
std::string get_gizmo_entering_text() const override { return _u8L("Entering Seam painting"); } std::string get_gizmo_entering_text() const override { return _u8L("Entering Seam painting"); }
std::string get_gizmo_leaving_text() const override { return _u8L("Leaving Seam painting"); } std::string get_gizmo_leaving_text() const override { return _u8L("Leaving Seam painting"); }
std::string get_action_snapshot_name() override { return _u8L("Paint-on seam editing"); } std::string get_action_snapshot_name() const override { return _u8L("Paint-on seam editing"); }
private: private:
bool on_init() override; bool on_init() override;

View File

@ -318,6 +318,7 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi
m_configuration.use_count = !m_configuration.use_count; m_configuration.use_count = !m_configuration.use_count;
start_process = true; start_process = true;
} else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && is_multipart) } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && is_multipart)
// TRN %1% = "Detail level", %2% = "Decimate ratio"
ImGui::SetTooltip("%s", GUI::format(_L( ImGui::SetTooltip("%s", GUI::format(_L(
"Multipart object can be simplified only by %1%. " "Multipart object can be simplified only by %1%. "
"If you want specify %2% process it separately."), "If you want specify %2% process it separately."),
@ -539,7 +540,8 @@ void GLGizmoSimplify::apply_simplify() {
const Selection& selection = m_parent.get_selection(); const Selection& selection = m_parent.get_selection();
auto plater = wxGetApp().plater(); auto plater = wxGetApp().plater();
plater->take_snapshot(_u8L("Simplify ") + create_volumes_name(m_volume_ids, selection)); // TRN %1% = volumes name
plater->take_snapshot(Slic3r::format(_u8L("Simplify %1%"), create_volumes_name(m_volume_ids, selection)));
plater->clear_before_change_mesh(selection.get_object_idx(), _u8L("Custom supports, seams and multimaterial painting were " plater->clear_before_change_mesh(selection.get_object_idx(), _u8L("Custom supports, seams and multimaterial painting were "
"removed after simplifying the mesh.")); "removed after simplifying the mesh."));
// After removing custom supports, seams, and multimaterial painting, we have to update info about the object to remove information about // After removing custom supports, seams, and multimaterial painting, we have to update info about the object to remove information about

View File

@ -1,10 +1,9 @@
#ifndef slic3r_GLGizmoSimplify_hpp_ #ifndef slic3r_GLGizmoSimplify_hpp_
#define slic3r_GLGizmoSimplify_hpp_ #define slic3r_GLGizmoSimplify_hpp_
// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code,
// which overrides our localization "L" macro.
#include "GLGizmoBase.hpp" #include "GLGizmoBase.hpp"
#include "slic3r/GUI/3DScene.hpp" #include "slic3r/GUI/3DScene.hpp"
#include "slic3r/GUI/I18N.hpp"
#include "admesh/stl.h" // indexed_triangle_set #include "admesh/stl.h" // indexed_triangle_set
#include <mutex> #include <mutex>
#include <thread> #include <thread>

View File

@ -1,5 +1,4 @@
#include "libslic3r/libslic3r.h" #include "libslic3r/libslic3r.h"
// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro.
#include "GLGizmoSlaSupports.hpp" #include "GLGizmoSlaSupports.hpp"
#include "slic3r/GUI/MainFrame.hpp" #include "slic3r/GUI/MainFrame.hpp"
#include "slic3r/Utils/UndoRedo.hpp" #include "slic3r/Utils/UndoRedo.hpp"

View File

@ -3,6 +3,7 @@
#include "GLGizmoSlaBase.hpp" #include "GLGizmoSlaBase.hpp"
#include "slic3r/GUI/GLSelectionRectangle.hpp" #include "slic3r/GUI/GLSelectionRectangle.hpp"
#include "slic3r/GUI/I18N.hpp"
#include "libslic3r/SLA/SupportPoint.hpp" #include "libslic3r/SLA/SupportPoint.hpp"
#include "libslic3r/ObjectID.hpp" #include "libslic3r/ObjectID.hpp"

View File

@ -344,7 +344,7 @@ void HintDatabase::load_hints_from_file(const boost::filesystem::path& path)
bool was_displayed = is_used(id_string); bool was_displayed = is_used(id_string);
//unescape text1 //unescape text1
unescape_string_cstyle(dict["text"], fulltext); unescape_string_cstyle(dict["text"], fulltext);
fulltext = _utf8(fulltext); fulltext = into_u8(_(fulltext));
#ifdef __APPLE__ #ifdef __APPLE__
boost::replace_all(fulltext, "Ctrl+", ""); boost::replace_all(fulltext, "Ctrl+", "");
#endif //__APPLE__ #endif //__APPLE__
@ -370,19 +370,19 @@ void HintDatabase::load_hints_from_file(const boost::filesystem::path& path)
fulltext.erase(hypertext_start, HYPERTEXT_MARKER_START.size()); fulltext.erase(hypertext_start, HYPERTEXT_MARKER_START.size());
if (fulltext.find(HYPERTEXT_MARKER_START) != std::string::npos) { if (fulltext.find(HYPERTEXT_MARKER_START) != std::string::npos) {
// This must not happen - only 1 hypertext allowed // This must not happen - only 1 hypertext allowed
BOOST_LOG_TRIVIAL(error) << "Hint notification with multiple hypertexts: " << _utf8(dict["text"]); BOOST_LOG_TRIVIAL(error) << "Hint notification with multiple hypertexts: " << dict["text"];
continue; continue;
} }
size_t hypertext_end = fulltext.find(HYPERTEXT_MARKER_END); size_t hypertext_end = fulltext.find(HYPERTEXT_MARKER_END);
if (hypertext_end == std::string::npos) { if (hypertext_end == std::string::npos) {
// hypertext was not correctly ended // hypertext was not correctly ended
BOOST_LOG_TRIVIAL(error) << "Hint notification without hypertext end marker: " << _utf8(dict["text"]); BOOST_LOG_TRIVIAL(error) << "Hint notification without hypertext end marker: " << dict["text"];
continue; continue;
} }
fulltext.erase(hypertext_end, HYPERTEXT_MARKER_END.size()); fulltext.erase(hypertext_end, HYPERTEXT_MARKER_END.size());
if (fulltext.find(HYPERTEXT_MARKER_END) != std::string::npos) { if (fulltext.find(HYPERTEXT_MARKER_END) != std::string::npos) {
// This must not happen - only 1 hypertext end allowed // This must not happen - only 1 hypertext end allowed
BOOST_LOG_TRIVIAL(error) << "Hint notification with multiple hypertext end markers: " << _utf8(dict["text"]); BOOST_LOG_TRIVIAL(error) << "Hint notification with multiple hypertext end markers: " << dict["text"];
continue; continue;
} }

View File

@ -1,7 +1,6 @@
#ifndef _ #ifndef _
#define _(s) Slic3r::GUI::I18N::translate((s)) #define _(s) Slic3r::GUI::I18N::translate((s))
#define _L(s) Slic3r::GUI::I18N::translate((s)) #define _L(s) Slic3r::GUI::I18N::translate((s))
#define _utf8(s) Slic3r::GUI::I18N::translate_utf8((s))
#define _u8L(s) Slic3r::GUI::I18N::translate_utf8((s)) #define _u8L(s) Slic3r::GUI::I18N::translate_utf8((s))
#endif /* _ */ #endif /* _ */

View File

@ -145,7 +145,7 @@ void CreateVolumeJob::finalize(bool canceled, std::exception_ptr &eptr) {
if (!priv::finalize(canceled, eptr, m_input)) if (!priv::finalize(canceled, eptr, m_input))
return; return;
if (m_result.its.empty()) if (m_result.its.empty())
return priv::create_message(_u8L("Can't create empty volume.")); return priv::create_message("Can't create empty volume.");
priv::create_volume(std::move(m_result), m_input.object_id, m_input.volume_type, m_input.trmat, m_input); priv::create_volume(std::move(m_result), m_input.object_id, m_input.volume_type, m_input.trmat, m_input);
} }
@ -198,7 +198,7 @@ void CreateObjectJob::finalize(bool canceled, std::exception_ptr &eptr)
// only for sure // only for sure
if (m_result.empty()) if (m_result.empty())
return priv::create_message(_u8L("Can't create empty object.")); return priv::create_message("Can't create empty object.");
GUI_App &app = wxGetApp(); GUI_App &app = wxGetApp();
Plater *plater = app.plater(); Plater *plater = app.plater();
@ -462,8 +462,8 @@ TriangleMesh priv::create_mesh(DataBase &input, Fnc was_canceled, Job::Ctl& ctl)
if (was_canceled()) return {}; if (was_canceled()) return {};
// only info // only info
ctl.call_on_main_thread([]() { ctl.call_on_main_thread([]() {
create_message(_u8L("It is used default volume for embossed " create_message("It is used default volume for embossed "
"text, try to change text or font to fix it.")); "text, try to change text or font to fix it.");
}); });
} }
@ -593,10 +593,10 @@ void priv::create_volume(
// Parent object for text volume was propably removed. // Parent object for text volume was propably removed.
// Assumption: User know what he does, so text volume is no more needed. // Assumption: User know what he does, so text volume is no more needed.
if (obj == nullptr) if (obj == nullptr)
return priv::create_message(_u8L("Bad object to create volume.")); return priv::create_message("Bad object to create volume.");
if (mesh.its.empty()) if (mesh.its.empty())
return priv::create_message(_u8L("Can't create empty volume.")); return priv::create_message("Can't create empty volume.");
plater->take_snapshot(_L("Add Emboss text Volume")); plater->take_snapshot(_L("Add Emboss text Volume"));
@ -823,10 +823,6 @@ bool priv::finalize(bool canceled, std::exception_ptr &eptr, const DataBase &inp
return !process(eptr); return !process(eptr);
} }
#include <wx/msgdlg.h>
void priv::create_message(const std::string &message) { void priv::create_message(const std::string &message) {
wxMessageBox(wxString(message), _L("Issue during embossing the text."), show_error(nullptr, message.c_str());
wxOK | wxICON_WARNING);
} }

View File

@ -124,4 +124,14 @@ void RotoptimizeJob::finalize(bool canceled, std::exception_ptr &eptr)
m_plater->update(); m_plater->update();
} }
std::string RotoptimizeJob::get_method_name(size_t i)
{
return into_u8(_(Methods[i].name));
}
std::string RotoptimizeJob::get_method_description(size_t i)
{
return into_u8(_(Methods[i].descr));
}
}} }}

View File

@ -58,15 +58,9 @@ public:
static constexpr size_t get_methods_count() { return std::size(Methods); } static constexpr size_t get_methods_count() { return std::size(Methods); }
static std::string get_method_name(size_t i) static std::string get_method_name(size_t i);
{
return _utf8(Methods[i].name);
}
static std::string get_method_description(size_t i) static std::string get_method_description(size_t i);
{
return _utf8(Methods[i].descr);
}
}; };
}} // namespace Slic3r::GUI }} // namespace Slic3r::GUI

View File

@ -30,7 +30,7 @@ std::string get_readers_wildcard()
std::string ret; std::string ret;
for (const char *archtype : SLAArchiveReader::registered_archives()) { for (const char *archtype : SLAArchiveReader::registered_archives()) {
ret += _utf8(SLAArchiveReader::get_description(archtype)); ret += into_u8(_(SLAArchiveReader::get_description(archtype)));
ret += " ("; ret += " (";
auto extensions = SLAArchiveReader::get_extensions(archtype); auto extensions = SLAArchiveReader::get_extensions(archtype);
for (const char * ext : extensions) { for (const char * ext : extensions) {

View File

@ -163,7 +163,7 @@ void SLAImportJob::finalize(bool canceled, std::exception_ptr &eptr)
p->plater->get_notification_manager()->push_notification( p->plater->get_notification_manager()->push_notification(
NotificationType::CustomNotification, NotificationType::CustomNotification,
NotificationManager::NotificationLevel::WarningNotificationLevel, NotificationManager::NotificationLevel::WarningNotificationLevel,
_u8L("The profile in the imported archive is corrupt and will not be loaded.")); _u8L("The profile in the imported archive is corrupted and will not be loaded."));
} }
} }

View File

@ -314,9 +314,9 @@ void MainFrame::bind_diff_dialog()
process(diff_dlg_type); process(diff_dlg_type);
}; };
diff_dialog.Bind(EVT_DIFF_DIALOG_TRANSFER, [this, process_options, transfer](SimpleEvent&) { process_options(transfer); }); diff_dialog.Bind(EVT_DIFF_DIALOG_TRANSFER, [process_options, transfer](SimpleEvent&) { process_options(transfer); });
diff_dialog.Bind(EVT_DIFF_DIALOG_UPDATE_PRESETS,[this, process_options, update_presets](SimpleEvent&) { process_options(update_presets); }); diff_dialog.Bind(EVT_DIFF_DIALOG_UPDATE_PRESETS,[process_options, update_presets](SimpleEvent&) { process_options(update_presets); });
} }
@ -1198,10 +1198,10 @@ static void add_common_view_menu_items(wxMenu* view_menu, MainFrame* mainFrame,
append_menu_item(view_menu, wxID_ANY, _L("Iso") + sep + "&0", _L("Iso View"), [mainFrame](wxCommandEvent&) { mainFrame->select_view("iso"); }, append_menu_item(view_menu, wxID_ANY, _L("Iso") + sep + "&0", _L("Iso View"), [mainFrame](wxCommandEvent&) { mainFrame->select_view("iso"); },
"", nullptr, [can_change_view]() { return can_change_view(); }, mainFrame); "", nullptr, [can_change_view]() { return can_change_view(); }, mainFrame);
view_menu->AppendSeparator(); view_menu->AppendSeparator();
//TRN To be shown in the main menu View->Top //TRN Main menu: View->Top
append_menu_item(view_menu, wxID_ANY, _L("Top") + sep + "&1", _L("Top View"), [mainFrame](wxCommandEvent&) { mainFrame->select_view("top"); }, append_menu_item(view_menu, wxID_ANY, _L("Top") + sep + "&1", _L("Top View"), [mainFrame](wxCommandEvent&) { mainFrame->select_view("top"); },
"", nullptr, [can_change_view]() { return can_change_view(); }, mainFrame); "", nullptr, [can_change_view]() { return can_change_view(); }, mainFrame);
//TRN To be shown in the main menu View->Bottom //TRN Main menu: View->Bottom
append_menu_item(view_menu, wxID_ANY, _L("Bottom") + sep + "&2", _L("Bottom View"), [mainFrame](wxCommandEvent&) { mainFrame->select_view("bottom"); }, append_menu_item(view_menu, wxID_ANY, _L("Bottom") + sep + "&2", _L("Bottom View"), [mainFrame](wxCommandEvent&) { mainFrame->select_view("bottom"); },
"", nullptr, [can_change_view]() { return can_change_view(); }, mainFrame); "", nullptr, [can_change_view]() { return can_change_view(); }, mainFrame);
append_menu_item(view_menu, wxID_ANY, _L("Front") + sep + "&3", _L("Front View"), [mainFrame](wxCommandEvent&) { mainFrame->select_view("front"); }, append_menu_item(view_menu, wxID_ANY, _L("Front") + sep + "&3", _L("Front View"), [mainFrame](wxCommandEvent&) { mainFrame->select_view("front"); },
@ -1638,7 +1638,7 @@ void MainFrame::init_menubar_as_gcodeviewer()
viewMenu = new wxMenu(); viewMenu = new wxMenu();
add_common_view_menu_items(viewMenu, this, std::bind(&MainFrame::can_change_view, this)); add_common_view_menu_items(viewMenu, this, std::bind(&MainFrame::can_change_view, this));
viewMenu->AppendSeparator(); viewMenu->AppendSeparator();
append_menu_check_item(viewMenu, wxID_ANY, _L("Show legen&d") + sep + "L", _L("Show legend"), append_menu_check_item(viewMenu, wxID_ANY, _L("Show Legen&d") + sep + "L", _L("Show legend"),
[this](wxCommandEvent&) { m_plater->show_legend(!m_plater->is_legend_shown()); }, this, [this](wxCommandEvent&) { m_plater->show_legend(!m_plater->is_legend_shown()); }, this,
[this]() { return m_plater->is_preview_shown(); }, [this]() { return m_plater->is_legend_shown(); }, this); [this]() { return m_plater->is_preview_shown(); }, [this]() { return m_plater->is_legend_shown(); }, this);
} }
@ -1755,7 +1755,7 @@ void MainFrame::quick_slice(const int qs)
} }
else if (qs & qsSaveAs) { else if (qs & qsSaveAs) {
// The following line may die if the output_filename_format template substitution fails. // The following line may die if the output_filename_format template substitution fails.
wxFileDialog dlg(this, from_u8((boost::format(_utf8(L("Save %s file as:"))) % ((qs & qsExportSVG) ? _L("SVG") : _L("G-code"))).str()), wxFileDialog dlg(this, format_wxstr(_L("Save %s file as:"), ((qs & qsExportSVG) ? _L("SVG") : _L("G-code"))),
wxGetApp().app_config->get_last_output_dir(get_dir_name(output_file)), get_base_name(input_file), wxGetApp().app_config->get_last_output_dir(get_dir_name(output_file)), get_base_name(input_file),
qs & qsExportSVG ? file_wildcards(FT_SVG) : file_wildcards(FT_GCODE), qs & qsExportSVG ? file_wildcards(FT_SVG) : file_wildcards(FT_GCODE),
wxFD_SAVE | wxFD_OVERWRITE_PROMPT); wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
@ -1777,8 +1777,8 @@ void MainFrame::quick_slice(const int qs)
// show processbar dialog // show processbar dialog
m_progress_dialog = new wxProgressDialog(_L("Slicing") + dots, m_progress_dialog = new wxProgressDialog(_L("Slicing") + dots,
// TRN "Processing input_file_basename" // TRN ProgressDialog on reslicing: "input file basename"
from_u8((boost::format(_utf8(L("Processing %s"))) % (input_file_basename + dots)).str()), format_wxstr(_L("Processing %s"), (input_file_basename + dots)),
100, nullptr, wxPD_AUTO_HIDE); 100, nullptr, wxPD_AUTO_HIDE);
m_progress_dialog->Pulse(); m_progress_dialog->Pulse();
{ {

View File

@ -866,7 +866,7 @@ bool NotificationManager::ExportFinishedNotification::on_text_click()
} }
void NotificationManager::ExportFinishedNotification::on_eject_click() void NotificationManager::ExportFinishedNotification::on_eject_click()
{ {
NotificationData data{ get_data().type, get_data().level , 0, _utf8("Ejecting.") }; NotificationData data{ get_data().type, get_data().level , 0, _u8L("Ejecting.") };
m_eject_pending = true; m_eject_pending = true;
m_multiline = false; m_multiline = false;
update(data); update(data);
@ -2447,7 +2447,7 @@ void NotificationManager::push_download_URL_progress_notification(size_t id, con
} }
} }
// push new one // push new one
NotificationData data{ NotificationType::URLDownload, NotificationLevel::ProgressBarNotificationLevel, 5, _utf8("Download:") + " " + text }; NotificationData data{ NotificationType::URLDownload, NotificationLevel::ProgressBarNotificationLevel, 5, _u8L("Download") + ": " + text };
push_notification_data(std::make_unique<NotificationManager::URLDownloadNotification>(data, m_id_provider, m_evt_handler, id, user_action_callback), 0); push_notification_data(std::make_unique<NotificationManager::URLDownloadNotification>(data, m_id_provider, m_evt_handler, id, user_action_callback), 0);
} }

View File

@ -173,8 +173,8 @@ wxPoint OG_CustomCtrl::get_pos(const Line& line, Field* field_in/* = nullptr*/)
ConfigOptionDef option = opt.opt; ConfigOptionDef option = opt.opt;
// add label if any // add label if any
if (is_multioption_line && !option.label.empty()) { if (is_multioption_line && !option.label.empty()) {
//! To correct translation by context have to use wxGETTEXT_IN_CONTEXT macro from wxWidget 3.1.1 // those two parameter names require localization with context
label = (option.label == L_CONTEXT("Top", "Layers") || option.label == L_CONTEXT("Bottom", "Layers")) ? label = (option.label == "Top" || option.label == "Bottom") ?
_CTX(option.label, "Layers") : _(option.label); _CTX(option.label, "Layers") : _(option.label);
label += ":"; label += ":";
@ -622,9 +622,9 @@ void OG_CustomCtrl::CtrlLine::render(wxDC& dc, wxCoord v_pos)
ConfigOptionDef option = opt.opt; ConfigOptionDef option = opt.opt;
// add label if any // add label if any
if (is_multioption_line && !option.label.empty()) { if (is_multioption_line && !option.label.empty()) {
//! To correct translation by context have to use wxGETTEXT_IN_CONTEXT macro from wxWidget 3.1.1 // those two parameter names require localization with context
label = (option.label == L_CONTEXT("Top", "Layers") || option.label == L_CONTEXT("Bottom", "Layers")) ? label = (option.label == "Top" || option.label == "Bottom") ?
_CTX(option.label, "Layers") : _(option.label); _CTX(option.label, "Layers") : _(option.label);
label += ":"; label += ":";
if (is_url_string) if (is_url_string)

View File

@ -11,7 +11,6 @@
#include "libslic3r/PrintConfig.hpp" #include "libslic3r/PrintConfig.hpp"
#include "OptionsGroup.hpp" #include "OptionsGroup.hpp"
#include "I18N.hpp"
// Translate the ifdef // Translate the ifdef
#ifdef __WXOSX__ #ifdef __WXOSX__

View File

@ -371,16 +371,16 @@ bool OpenGLManager::init_gl()
if (!valid_version) { if (!valid_version) {
// Complain about the OpenGL version. // Complain about the OpenGL version.
wxString message = from_u8((boost::format( wxString message = format_wxstr(
#if ENABLE_OPENGL_ES #if ENABLE_OPENGL_ES
_utf8(L("PrusaSlicer requires OpenGL ES 2.0 capable graphics driver to run correctly, \n" _L("PrusaSlicer requires OpenGL ES 2.0 capable graphics driver to run correctly, \n"
"while OpenGL version %s, render %s, vendor %s was detected."))) % s_gl_info.get_version_string() % s_gl_info.get_renderer() % s_gl_info.get_vendor()).str()); "while OpenGL version %s, render %s, vendor %s was detected."), s_gl_info.get_version_string(), s_gl_info.get_renderer(), s_gl_info.get_vendor());
#elif ENABLE_GL_CORE_PROFILE #elif ENABLE_GL_CORE_PROFILE
_utf8(L("PrusaSlicer requires OpenGL %s capable graphics driver to run correctly, \n" _L("PrusaSlicer requires OpenGL %s capable graphics driver to run correctly, \n"
"while OpenGL version %s, render %s, vendor %s was detected."))) % (s_gl_info.is_core_profile() ? "3.3" : "2.0") % s_gl_info.get_version_string() % s_gl_info.get_renderer() % s_gl_info.get_vendor()).str()); "while OpenGL version %s, render %s, vendor %s was detected."), (s_gl_info.is_core_profile() ? "3.3" : "2.0"), s_gl_info.get_version_string(), s_gl_info.get_renderer(), s_gl_info.get_vendor());
#else #else
_utf8(L("PrusaSlicer requires OpenGL 2.0 capable graphics driver to run correctly, \n" _L("PrusaSlicer requires OpenGL 2.0 capable graphics driver to run correctly, \n"
"while OpenGL version %s, render %s, vendor %s was detected."))) % s_gl_info.get_version_string() % s_gl_info.get_renderer() % s_gl_info.get_vendor()).str()); "while OpenGL version %s, render %s, vendor %s was detected."), s_gl_info.get_version_string(), s_gl_info.get_renderer(), s_gl_info.get_vendor());
#endif // ENABLE_OPENGL_ES #endif // ENABLE_OPENGL_ES
message += "\n"; message += "\n";
message += _L("You may need to update your graphics card driver."); message += _L("You may need to update your graphics card driver.");
@ -395,8 +395,7 @@ bool OpenGLManager::init_gl()
// load shaders // load shaders
auto [result, error] = m_shaders_manager.init(); auto [result, error] = m_shaders_manager.init();
if (!result) { if (!result) {
wxString message = from_u8((boost::format( wxString message = format_wxstr(_L("Unable to load the following shaders:\n%s"), error);
_utf8(L("Unable to load the following shaders:\n%s"))) % error).str());
wxMessageBox(message, wxString("PrusaSlicer - ") + _L("Error loading shaders"), wxOK | wxICON_ERROR); wxMessageBox(message, wxString("PrusaSlicer - ") + _L("Error loading shaders"), wxOK | wxICON_ERROR);
} }
#if ENABLE_OPENGL_DEBUG_OPTION #if ENABLE_OPENGL_DEBUG_OPTION

View File

@ -384,8 +384,8 @@ void OptionsGroup::activate_line(Line& line)
ConfigOptionDef option = opt.opt; ConfigOptionDef option = opt.opt;
// add label if any // add label if any
if ((option_set.size() > 1 || line.label.IsEmpty()) && !option.label.empty()) { if ((option_set.size() > 1 || line.label.IsEmpty()) && !option.label.empty()) {
// To correct translation by context have to use wxGETTEXT_IN_CONTEXT macro from wxWidget 3.1.1 // those two parameter names require localization with context
wxString str_label = (option.label == L_CONTEXT("Top", "Layers") || option.label == L_CONTEXT("Bottom", "Layers")) ? wxString str_label = (option.label == "Top" || option.label == "Bottom") ?
_CTX(option.label, "Layers") : _CTX(option.label, "Layers") :
_(option.label); _(option.label);
label = new wxStaticText(this->ctrl_parent(), wxID_ANY, str_label + ": ", wxDefaultPosition, //wxDefaultSize); label = new wxStaticText(this->ctrl_parent(), wxID_ANY, str_label + ": ", wxDefaultPosition, //wxDefaultSize);

View File

@ -830,6 +830,7 @@ Sidebar::Sidebar(Plater *parent)
wxRIGHT, margin_5); wxRIGHT, margin_5);
#else #else
wxBOTTOM, 1); wxBOTTOM, 1);
(void)margin_5; // supress unused capture warning
#endif // __WXGTK3__ #endif // __WXGTK3__
} else { } else {
sizer_filaments->Add(combo_and_btn_sizer, 0, wxEXPAND | sizer_filaments->Add(combo_and_btn_sizer, 0, wxEXPAND |
@ -1376,7 +1377,7 @@ void Sidebar::update_sliced_info_sizer()
wxString t_est = std::isnan(ps.estimated_print_time) ? "N/A" : get_time_dhms(float(ps.estimated_print_time)); wxString t_est = std::isnan(ps.estimated_print_time) ? "N/A" : get_time_dhms(float(ps.estimated_print_time));
p->sliced_info->SetTextAndShow(siEstimatedTime, t_est, _L("Estimated printing time") + ":"); p->sliced_info->SetTextAndShow(siEstimatedTime, t_est, _L("Estimated printing time") + ":");
p->plater->get_notification_manager()->set_slicing_complete_print_time(_utf8("Estimated printing time: ") + boost::nowide::narrow(t_est), p->plater->is_sidebar_collapsed()); p->plater->get_notification_manager()->set_slicing_complete_print_time(_u8L("Estimated printing time") + ": " + boost::nowide::narrow(t_est), p->plater->is_sidebar_collapsed());
// Hide non-SLA sliced info parameters // Hide non-SLA sliced info parameters
p->sliced_info->SetTextAndShow(siFilament_m, "N/A"); p->sliced_info->SetTextAndShow(siFilament_m, "N/A");
@ -1466,7 +1467,7 @@ void Sidebar::update_sliced_info_sizer()
new_label += format_wxstr("\n - %1%", _L("normal mode")); new_label += format_wxstr("\n - %1%", _L("normal mode"));
info_text += format_wxstr("\n%1%", short_time(ps.estimated_normal_print_time)); info_text += format_wxstr("\n%1%", short_time(ps.estimated_normal_print_time));
p->plater->get_notification_manager()->set_slicing_complete_print_time(_utf8("Estimated printing time: ") + ps.estimated_normal_print_time, p->plater->is_sidebar_collapsed()); p->plater->get_notification_manager()->set_slicing_complete_print_time(_u8L("Estimated printing time") + ": " + ps.estimated_normal_print_time, p->plater->is_sidebar_collapsed());
} }
if (ps.estimated_silent_print_time != "N/A") { if (ps.estimated_silent_print_time != "N/A") {
@ -2016,7 +2017,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
, config(Slic3r::DynamicPrintConfig::new_from_defaults_keys({ , config(Slic3r::DynamicPrintConfig::new_from_defaults_keys({
"bed_shape", "bed_custom_texture", "bed_custom_model", "complete_objects", "duplicate_distance", "extruder_clearance_radius", "skirts", "skirt_distance", "bed_shape", "bed_custom_texture", "bed_custom_model", "complete_objects", "duplicate_distance", "extruder_clearance_radius", "skirts", "skirt_distance",
"brim_width", "brim_separation", "brim_type", "variable_layer_height", "nozzle_diameter", "single_extruder_multi_material", "brim_width", "brim_separation", "brim_type", "variable_layer_height", "nozzle_diameter", "single_extruder_multi_material",
"wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_cone_angle", "wipe_tower_extra_spacing",
"extruder_colour", "filament_colour", "material_colour", "max_print_height", "printer_model", "printer_technology", "extruder_colour", "filament_colour", "material_colour", "max_print_height", "printer_model", "printer_technology",
// These values are necessary to construct SlicingParameters by the Canvas3D variable layer height editor. // These values are necessary to construct SlicingParameters by the Canvas3D variable layer height editor.
"layer_height", "first_layer_height", "min_layer_height", "max_layer_height", "layer_height", "first_layer_height", "min_layer_height", "max_layer_height",
@ -2251,7 +2252,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
this->q->load_files(input_files); this->q->load_files(input_files);
}); });
this->q->Bind(EVT_START_DOWNLOAD_OTHER_INSTANCE, [this](StartDownloadOtherInstanceEvent& evt) { this->q->Bind(EVT_START_DOWNLOAD_OTHER_INSTANCE, [](StartDownloadOtherInstanceEvent& evt) {
BOOST_LOG_TRIVIAL(trace) << "Received url from other instance event."; BOOST_LOG_TRIVIAL(trace) << "Received url from other instance event.";
wxGetApp().mainframe->Raise(); wxGetApp().mainframe->Raise();
for (size_t i = 0; i < evt.data.size(); ++i) { for (size_t i = 0; i < evt.data.size(); ++i) {
@ -2343,8 +2344,8 @@ void Plater::priv::collapse_sidebar(bool collapse)
// Now update the tooltip in the toolbar. // Now update the tooltip in the toolbar.
std::string new_tooltip = collapse std::string new_tooltip = collapse
? _utf8(L("Expand sidebar")) ? _u8L("Expand sidebar")
: _utf8(L("Collapse sidebar")); : _u8L("Collapse sidebar");
new_tooltip += " [Shift+Tab]"; new_tooltip += " [Shift+Tab]";
int id = collapse_toolbar.get_item_id("collapse_sidebar"); int id = collapse_toolbar.get_item_id("collapse_sidebar");
collapse_toolbar.set_tooltip(id, new_tooltip); collapse_toolbar.set_tooltip(id, new_tooltip);
@ -3033,8 +3034,8 @@ bool Plater::priv::delete_object_from_model(size_t obj_idx)
ModelObject* obj = model.objects[obj_idx]; ModelObject* obj = model.objects[obj_idx];
if (obj->is_cut()) { if (obj->is_cut()) {
InfoDialog dialog(q, _L("Delete object which is a part of cut object"), InfoDialog dialog(q, _L("Delete object which is a part of cut object"),
_L("You try to delete an object which is a part of a cut object.\n" _L("You try to delete an object which is a part of a cut object.") + "\n" +
"This action will break a cut correspondence.\n" _L("This action will break a cut information.\n"
"After that PrusaSlicer can't guarantee model consistency"), "After that PrusaSlicer can't guarantee model consistency"),
false, wxYES | wxCANCEL | wxCANCEL_DEFAULT | wxICON_WARNING); false, wxYES | wxCANCEL | wxCANCEL_DEFAULT | wxICON_WARNING);
dialog.SetButtonLabel(wxID_YES, _L("Delete object")); dialog.SetButtonLabel(wxID_YES, _L("Delete object"));
@ -4251,7 +4252,7 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt)
} }
if (evt.cancelled()) { if (evt.cancelled()) {
// this->statusbar()->set_status_text(_L("Cancelled")); // this->statusbar()->set_status_text(_L("Cancelled"));
this->notification_manager->set_slicing_progress_canceled(_utf8("Slicing Cancelled.")); this->notification_manager->set_slicing_progress_canceled(_u8L("Slicing Cancelled."));
} }
this->sidebar->show_sliced_info_sizer(evt.success()); this->sidebar->show_sliced_info_sizer(evt.success());
@ -4558,7 +4559,7 @@ bool Plater::priv::init_view_toolbar()
item.name = "3D"; item.name = "3D";
item.icon_filename = "editor.svg"; item.icon_filename = "editor.svg";
item.tooltip = _utf8(L("3D editor view")) + " [" + GUI::shortkey_ctrl_prefix() + "5]"; item.tooltip = _u8L("3D editor view") + " [" + GUI::shortkey_ctrl_prefix() + "5]";
item.sprite_id = 0; item.sprite_id = 0;
item.left.action_callback = [this]() { if (this->q != nullptr) wxPostEvent(this->q, SimpleEvent(EVT_GLVIEWTOOLBAR_3D)); }; item.left.action_callback = [this]() { if (this->q != nullptr) wxPostEvent(this->q, SimpleEvent(EVT_GLVIEWTOOLBAR_3D)); };
if (!view_toolbar.add_item(item)) if (!view_toolbar.add_item(item))
@ -4566,7 +4567,7 @@ bool Plater::priv::init_view_toolbar()
item.name = "Preview"; item.name = "Preview";
item.icon_filename = "preview.svg"; item.icon_filename = "preview.svg";
item.tooltip = _utf8(L("Preview")) + " [" + GUI::shortkey_ctrl_prefix() + "6]"; item.tooltip = _u8L("Preview") + " [" + GUI::shortkey_ctrl_prefix() + "6]";
item.sprite_id = 1; item.sprite_id = 1;
item.left.action_callback = [this]() { if (this->q != nullptr) wxPostEvent(this->q, SimpleEvent(EVT_GLVIEWTOOLBAR_PREVIEW)); }; item.left.action_callback = [this]() { if (this->q != nullptr) wxPostEvent(this->q, SimpleEvent(EVT_GLVIEWTOOLBAR_PREVIEW)); };
if (!view_toolbar.add_item(item)) if (!view_toolbar.add_item(item))
@ -4779,7 +4780,7 @@ bool Plater::priv::can_increase_instances() const
if (q->canvas3D()->get_gizmos_manager().get_current_type() == GLGizmosManager::Emboss) return false; if (q->canvas3D()->get_gizmos_manager().get_current_type() == GLGizmosManager::Emboss) return false;
const auto obj_idxs = get_selection().get_object_idxs(); const auto obj_idxs = get_selection().get_object_idxs();
return !obj_idxs.empty() && !sidebar->obj_list()->has_selected_cut_object(); return !obj_idxs.empty() && !get_selection().is_wipe_tower() && !sidebar->obj_list()->has_selected_cut_object();
} }
bool Plater::priv::can_decrease_instances(int obj_idx /*= -1*/) const bool Plater::priv::can_decrease_instances(int obj_idx /*= -1*/) const
@ -5437,7 +5438,7 @@ protected:
LoadProjectsDialog::LoadProjectsDialog(const std::vector<fs::path>& paths) LoadProjectsDialog::LoadProjectsDialog(const std::vector<fs::path>& paths)
: DPIDialog(static_cast<wxWindow*>(wxGetApp().mainframe), wxID_ANY, : DPIDialog(static_cast<wxWindow*>(wxGetApp().mainframe), wxID_ANY,
from_u8((boost::format(_utf8(L("%s - Multiple projects file"))) % SLIC3R_APP_NAME).str()), wxDefaultPosition, format_wxstr(_L("%1% - Multiple projects file"), SLIC3R_APP_NAME), wxDefaultPosition,
wxDefaultSize, wxDEFAULT_DIALOG_STYLE) wxDefaultSize, wxDEFAULT_DIALOG_STYLE)
{ {
SetFont(wxGetApp().normal_font()); SetFont(wxGetApp().normal_font());
@ -5557,7 +5558,7 @@ bool Plater::preview_zip_archive(const boost::filesystem::path& archive_path)
mz_zip_zero_struct(&archive); mz_zip_zero_struct(&archive);
if (!open_zip_reader(&archive, archive_path.string())) { if (!open_zip_reader(&archive, archive_path.string())) {
std::string err_msg = GUI::format(_utf8("Loading of a zip archive on path %1% has failed."), archive_path.string()); std::string err_msg = GUI::format(_u8L("Loading of a zip archive on path %1% has failed."), archive_path.string());
throw Slic3r::FileIOError(err_msg); throw Slic3r::FileIOError(err_msg);
} }
mz_uint num_entries = mz_zip_reader_get_num_files(&archive); mz_uint num_entries = mz_zip_reader_get_num_files(&archive);
@ -5826,9 +5827,7 @@ protected:
ProjectDropDialog::ProjectDropDialog(const std::string& filename) ProjectDropDialog::ProjectDropDialog(const std::string& filename)
: DPIDialog(static_cast<wxWindow*>(wxGetApp().mainframe), wxID_ANY, : DPIDialog(static_cast<wxWindow*>(wxGetApp().mainframe), wxID_ANY,
// #ysFIXME_delete_after_test_of_6377 format_wxstr("%1% - %2%", SLIC3R_APP_NAME, _L("Load project file")), wxDefaultPosition,
// from_u8((boost::format(_utf8(L("%s - Drop project file"))) % SLIC3R_APP_NAME).str()), wxDefaultPosition,
from_u8((boost::format(_utf8(L("%s - Load project file"))) % SLIC3R_APP_NAME).str()), wxDefaultPosition,
wxDefaultSize, wxDEFAULT_DIALOG_STYLE) wxDefaultSize, wxDEFAULT_DIALOG_STYLE)
{ {
SetFont(wxGetApp().normal_font()); SetFont(wxGetApp().normal_font());
@ -5936,7 +5935,7 @@ bool Plater::load_files(const wxArrayString& filenames, bool delete_after_load/*
std::string filename = (*it).filename().string(); std::string filename = (*it).filename().string();
if (boost::algorithm::iends_with(filename, ".3mf") || boost::algorithm::iends_with(filename, ".amf")) { if (boost::algorithm::iends_with(filename, ".3mf") || boost::algorithm::iends_with(filename, ".amf")) {
ProjectDropDialog::LoadType load_type = ProjectDropDialog::LoadType::Unknown; ProjectDropDialog::LoadType load_type = ProjectDropDialog::LoadType::Unknown;
// if (!model().objects.empty()) { // #ysFIXME_delete_after_test_of_6377 {
if ((boost::algorithm::iends_with(filename, ".3mf") && !is_project_3mf(it->string())) || if ((boost::algorithm::iends_with(filename, ".3mf") && !is_project_3mf(it->string())) ||
(boost::algorithm::iends_with(filename, ".amf") && !boost::algorithm::iends_with(filename, ".zip.amf"))) (boost::algorithm::iends_with(filename, ".amf") && !boost::algorithm::iends_with(filename, ".zip.amf")))
load_type = ProjectDropDialog::LoadType::LoadGeometry; load_type = ProjectDropDialog::LoadType::LoadGeometry;
@ -5953,11 +5952,7 @@ bool Plater::load_files(const wxArrayString& filenames, bool delete_after_load/*
load_type = static_cast<ProjectDropDialog::LoadType>(std::clamp(std::stoi(wxGetApp().app_config->get("drop_project_action")), load_type = static_cast<ProjectDropDialog::LoadType>(std::clamp(std::stoi(wxGetApp().app_config->get("drop_project_action")),
static_cast<int>(ProjectDropDialog::LoadType::OpenProject), static_cast<int>(ProjectDropDialog::LoadType::LoadConfig))); static_cast<int>(ProjectDropDialog::LoadType::OpenProject), static_cast<int>(ProjectDropDialog::LoadType::LoadConfig)));
} }
/* // #ysFIXME_delete_after_test_of_6377
} }
else
load_type = ProjectDropDialog::LoadType::OpenProject;
*/
if (load_type == ProjectDropDialog::LoadType::Unknown) if (load_type == ProjectDropDialog::LoadType::Unknown)
return false; return false;

View File

@ -308,14 +308,9 @@ void PreferencesDialog::build()
m_optgroup_general->append_separator(); m_optgroup_general->append_separator();
append_bool_option(m_optgroup_general, "show_drop_project_dialog", append_bool_option(m_optgroup_general, "show_drop_project_dialog",
#if 1 // #ysFIXME_delete_after_test_of_6377
L("Show load project dialog"), L("Show load project dialog"),
L("When checked, whenever dragging and dropping a project file on the application or open it from a browser, " L("When checked, whenever dragging and dropping a project file on the application or open it from a browser, "
"shows a dialog asking to select the action to take on the file to load."), "shows a dialog asking to select the action to take on the file to load."),
#else
L("Show drop project dialog"),
L("When checked, whenever dragging and dropping a project file on the application, shows a dialog asking to select the action to take on the file to load."),
#endif
app_config->get_bool("show_drop_project_dialog")); app_config->get_bool("show_drop_project_dialog"));
append_bool_option(m_optgroup_general, "single_instance", append_bool_option(m_optgroup_general, "single_instance",
@ -471,7 +466,7 @@ void PreferencesDialog::build()
append_bool_option(m_optgroup_gui, "seq_top_layer_only", append_bool_option(m_optgroup_gui, "seq_top_layer_only",
L("Sequential slider applied only to top layer"), L("Sequential slider applied only to top layer"),
L("If enabled, changes made using the sequential slider, in preview, apply only to gcode top layer." L("If enabled, changes made using the sequential slider, in preview, apply only to gcode top layer. "
"If disabled, changes made using the sequential slider, in preview, apply to the whole gcode."), "If disabled, changes made using the sequential slider, in preview, apply to the whole gcode."),
app_config->get_bool("seq_top_layer_only")); app_config->get_bool("seq_top_layer_only"));
@ -627,7 +622,7 @@ void PreferencesDialog::build()
append_bool_option(m_optgroup_dark_mode, "sys_menu_enabled", append_bool_option(m_optgroup_dark_mode, "sys_menu_enabled",
L("Use system menu for application"), L("Use system menu for application"),
L("If enabled, application will use the standard Windows system menu,\n" L("If enabled, application will use the standard Windows system menu,\n"
"but on some combination od display scales it can look ugly. If disabled, old UI will be used."), "but on some combination of display scales it can look ugly. If disabled, old UI will be used."),
app_config->get_bool("sys_menu_enabled")); app_config->get_bool("sys_menu_enabled"));
} }

View File

@ -163,7 +163,7 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
double volumetric_flow = flow.mm3_per_mm() * (bridging ? bridge_speed : limit_by_first_layer_speed(speed, max_print_speed)); double volumetric_flow = flow.mm3_per_mm() * (bridging ? bridge_speed : limit_by_first_layer_speed(speed, max_print_speed));
if (max_flow < volumetric_flow) { if (max_flow < volumetric_flow) {
max_flow = volumetric_flow; max_flow = volumetric_flow;
max_flow_extrusion_type = _utf8(err_msg); max_flow_extrusion_type = GUI::into_u8(_(err_msg));
} }
}; };
if (perimeter_extruder_active) { if (perimeter_extruder_active) {
@ -184,17 +184,17 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
//FIXME handle gap_fill_speed //FIXME handle gap_fill_speed
if (! out.empty()) if (! out.empty())
out += "\n"; out += "\n";
out += (first_layer ? _utf8(L("First layer volumetric")) : (bridging ? _utf8(L("Bridging volumetric")) : _utf8(L("Volumetric")))); out += (first_layer ? _u8L("First layer volumetric") : (bridging ? _u8L("Bridging volumetric") : _u8L("Volumetric")));
out += " " + _utf8(L("flow rate is maximized")) + " "; out += " " + _u8L("flow rate is maximized") + " ";
bool limited_by_max_volumetric_speed = max_volumetric_speed > 0 && max_volumetric_speed < max_flow; bool limited_by_max_volumetric_speed = max_volumetric_speed > 0 && max_volumetric_speed < max_flow;
out += (limited_by_max_volumetric_speed ? out += (limited_by_max_volumetric_speed ?
_utf8(L("by the print profile maximum")) : _u8L("by the print profile maximum") :
(_utf8(L("when printing"))+ " " + max_flow_extrusion_type)) (_u8L("when printing")+ " " + max_flow_extrusion_type))
+ " " + _utf8(L("with a volumetric rate"))+ " "; + " " + _u8L("with a volumetric rate")+ " ";
if (limited_by_max_volumetric_speed) if (limited_by_max_volumetric_speed)
max_flow = max_volumetric_speed; max_flow = max_volumetric_speed;
out += (boost::format(_utf8(L("%3.2f mm³/s at filament speed %3.2f mm/s."))) % max_flow % (max_flow / filament_crossection)).str(); out += format(_u8L("%3.2f mm³/s at filament speed %3.2f mm/s."), max_flow, (max_flow / filament_crossection));
} }
return out; return out;
@ -212,13 +212,13 @@ std::string PresetHints::recommended_thin_wall_thickness(const PresetBundle &pre
std::string out; std::string out;
if (layer_height <= 0.f) { if (layer_height <= 0.f) {
out += _utf8(L("Recommended object thin wall thickness: Not available due to invalid layer height.")); out += _u8L("Recommended object thin wall thickness: Not available due to invalid layer height.");
return out; return out;
} }
if (num_perimeters > 0) { if (num_perimeters > 0) {
int num_lines = std::min(num_perimeters * 2, 10); int num_lines = std::min(num_perimeters * 2, 10);
out += (boost::format(_utf8(L("Recommended object thin wall thickness for layer height %.2f and"))) % layer_height).str() + " "; out += (boost::format(_u8L("Recommended object thin wall thickness for layer height %.2f and")) % layer_height).str() + " ";
// Start with the width of two closely spaced // Start with the width of two closely spaced
try { try {
Flow external_perimeter_flow = Flow::new_from_config_width( Flow external_perimeter_flow = Flow::new_from_config_width(
@ -233,11 +233,11 @@ std::string PresetHints::recommended_thin_wall_thickness(const PresetBundle &pre
for (int i = 2; i <= num_lines; thin_walls ? ++ i : i += 2) { for (int i = 2; i <= num_lines; thin_walls ? ++ i : i += 2) {
if (i > 2) if (i > 2)
out += ", "; out += ", ";
out += (boost::format(_utf8(L("%d lines: %.2f mm"))) % i % width).str() + " "; out += (boost::format(_u8L("%d lines: %.2f mm")) % i % width).str() + " ";
width += perimeter_flow.spacing() * (thin_walls ? 1.f : 2.f); width += perimeter_flow.spacing() * (thin_walls ? 1.f : 2.f);
} }
} catch (const FlowErrorNegativeSpacing &) { } catch (const FlowErrorNegativeSpacing &) {
out = _utf8(L("Recommended object thin wall thickness: Not available due to excessively small extrusion width.")); out = _u8L("Recommended object thin wall thickness: Not available due to excessively small extrusion width.");
} }
} }
return out; return out;
@ -266,7 +266,7 @@ std::string PresetHints::top_bottom_shell_thickness_explanation(const PresetBund
double min_layer_height = variable_layer_height ? Slicing::min_layer_height_from_nozzle(printer_config, 1) : layer_height; double min_layer_height = variable_layer_height ? Slicing::min_layer_height_from_nozzle(printer_config, 1) : layer_height;
if (layer_height <= 0.f) { if (layer_height <= 0.f) {
out += _utf8(L("Top / bottom shell thickness hint: Not available due to invalid layer height.")); out += _u8L("Top / bottom shell thickness hint: Not available due to invalid layer height.");
return out; return out;
} }
@ -279,13 +279,13 @@ std::string PresetHints::top_bottom_shell_thickness_explanation(const PresetBund
top_shell_thickness = n * layer_height; top_shell_thickness = n * layer_height;
} }
double top_shell_thickness_minimum = std::max(top_solid_min_thickness, top_solid_layers * min_layer_height); double top_shell_thickness_minimum = std::max(top_solid_min_thickness, top_solid_layers * min_layer_height);
out += (boost::format(_utf8(L("Top shell is %1% mm thick for layer height %2% mm."))) % top_shell_thickness % layer_height).str(); out += (boost::format(_u8L("Top shell is %1% mm thick for layer height %2% mm.")) % top_shell_thickness % layer_height).str();
if (variable_layer_height && top_shell_thickness_minimum < top_shell_thickness) { if (variable_layer_height && top_shell_thickness_minimum < top_shell_thickness) {
out += " "; out += " ";
out += (boost::format(_utf8(L("Minimum top shell thickness is %1% mm."))) % top_shell_thickness_minimum).str(); out += (boost::format(_u8L("Minimum top shell thickness is %1% mm.")) % top_shell_thickness_minimum).str();
} }
} else } else
out += _utf8(L("Top is open.")); out += _u8L("Top is open.");
out += "\n"; out += "\n";
@ -298,13 +298,13 @@ std::string PresetHints::top_bottom_shell_thickness_explanation(const PresetBund
bottom_shell_thickness = n * layer_height; bottom_shell_thickness = n * layer_height;
} }
double bottom_shell_thickness_minimum = std::max(bottom_solid_min_thickness, bottom_solid_layers * min_layer_height); double bottom_shell_thickness_minimum = std::max(bottom_solid_min_thickness, bottom_solid_layers * min_layer_height);
out += (boost::format(_utf8(L("Bottom shell is %1% mm thick for layer height %2% mm."))) % bottom_shell_thickness % layer_height).str(); out += (boost::format(_u8L("Bottom shell is %1% mm thick for layer height %2% mm.")) % bottom_shell_thickness % layer_height).str();
if (variable_layer_height && bottom_shell_thickness_minimum < bottom_shell_thickness) { if (variable_layer_height && bottom_shell_thickness_minimum < bottom_shell_thickness) {
out += " "; out += " ";
out += (boost::format(_utf8(L("Minimum bottom shell thickness is %1% mm."))) % bottom_shell_thickness_minimum).str(); out += (boost::format(_u8L("Minimum bottom shell thickness is %1% mm.")) % bottom_shell_thickness_minimum).str();
} }
} else } else
out += _utf8(L("Bottom is open.")); out += _u8L("Bottom is open.");
return out; return out;
} }

View File

@ -71,7 +71,7 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, PrintHostPostUplo
if (combo_storage != nullptr) { if (combo_storage != nullptr) {
// PrusaLink specific: User needs to choose a storage // PrusaLink specific: User needs to choose a storage
auto* label_group = new wxStaticText(this, wxID_ANY, _L("Upload to storage:")); auto* label_group = new wxStaticText(this, wxID_ANY, _L("Upload to storage") + ":");
content_sizer->Add(label_group); content_sizer->Add(label_group);
content_sizer->Add(combo_storage, 0, wxBOTTOM, 2 * VERT_SPACING); content_sizer->Add(combo_storage, 0, wxBOTTOM, 2 * VERT_SPACING);
combo_storage->SetValue(storage_names.front()); combo_storage->SetValue(storage_names.front());
@ -80,7 +80,7 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, PrintHostPostUplo
combo_storage->SetValue(recent_storage); combo_storage->SetValue(recent_storage);
} else if (storage_names.GetCount() == 1){ } else if (storage_names.GetCount() == 1){
// PrusaLink specific: Show which storage has been detected. // PrusaLink specific: Show which storage has been detected.
auto* label_group = new wxStaticText(this, wxID_ANY, _L("Upload to storage: ") + storage_names.front()); auto* label_group = new wxStaticText(this, wxID_ANY, _L("Upload to storage") + ": " + storage_names.front());
content_sizer->Add(label_group); content_sizer->Add(label_group);
m_preselected_storage = storage_paths.front(); m_preselected_storage = storage_paths.front();
} }
@ -473,7 +473,7 @@ void PrintHostQueueDialog::on_error(Event &evt)
set_state(evt.job_id, ST_ERROR); set_state(evt.job_id, ST_ERROR);
auto errormsg = from_u8((boost::format("%1%\n%2%") % _utf8(L("Error uploading to print host:")) % std::string(evt.status.ToUTF8())).str()); auto errormsg = format_wxstr("%1%\n%2%", _L("Error uploading to print host") + ":", evt.status);
job_list->SetValue(wxVariant(0), evt.job_id, COL_PROGRESS); job_list->SetValue(wxVariant(0), evt.job_id, COL_PROGRESS);
job_list->SetValue(wxVariant(errormsg), evt.job_id, COL_ERRORMSG); // Stashes the error message into a hidden column for later job_list->SetValue(wxVariant(errormsg), evt.job_id, COL_ERRORMSG); // Stashes the error message into a hidden column for later

View File

@ -87,9 +87,13 @@ void SavePresetDialog::Item::init_input_name_ctrl(wxBoxSizer *input_name_sizer,
wxString SavePresetDialog::Item::get_top_label_text() const wxString SavePresetDialog::Item::get_top_label_text() const
{ {
const std::string label_str = m_use_text_ctrl ?_u8L("Rename %s to:") : _u8L("Save %s as:"); const std::string label_str = m_use_text_ctrl ?
// TRN %1% = "Preset"
L("Rename %1% to") :
// TRN %1% = "Preset"
L("Save %1% as");
Tab* tab = wxGetApp().get_tab(m_type); Tab* tab = wxGetApp().get_tab(m_type);
return from_u8((boost::format(label_str) % into_u8(tab->title())).str()); return format_wxstr(_(label_str) + ":", tab->title());
} }
SavePresetDialog::Item::Item(Preset::Type type, const std::string& suffix, wxBoxSizer* sizer, SavePresetDialog* parent): SavePresetDialog::Item::Item(Preset::Type type, const std::string& suffix, wxBoxSizer* sizer, SavePresetDialog* parent):
@ -324,6 +328,7 @@ void SavePresetDialog::build(std::vector<Preset::Type> types, std::string suffix
#endif // __WXMSW__ #endif // __WXMSW__
if (suffix.empty()) if (suffix.empty())
// TRN Suffix for the preset name. Have to be a noun.
suffix = _CTX_utf8(L_CONTEXT("Copy", "PresetName"), "PresetName"); suffix = _CTX_utf8(L_CONTEXT("Copy", "PresetName"), "PresetName");
wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL);

View File

@ -5,6 +5,7 @@
#include "slic3r/Utils/RaycastManager.hpp" #include "slic3r/Utils/RaycastManager.hpp"
#include "slic3r/GUI/Camera.hpp" #include "slic3r/GUI/Camera.hpp"
#include "slic3r/GUI/CameraUtils.hpp" #include "slic3r/GUI/CameraUtils.hpp"
#include "slic3r/GUI/I18N.hpp"
#include "libslic3r/Emboss.hpp" #include "libslic3r/Emboss.hpp"
namespace Slic3r::GUI { namespace Slic3r::GUI {

View File

@ -163,9 +163,10 @@ void Tab::create_preset_tab()
add_scaled_button(panel, &m_btn_hide_incompatible_presets, "flag_green"); add_scaled_button(panel, &m_btn_hide_incompatible_presets, "flag_green");
m_btn_compare_preset->SetToolTip(_L("Compare this preset with some another")); m_btn_compare_preset->SetToolTip(_L("Compare this preset with some another"));
// TRN "Save current Settings" // TRN Settings Tabs: Tooltip for save button: "Settings"
m_btn_save_preset->SetToolTip(from_u8((boost::format(_utf8(L("Save current %s"))) % m_title).str())); m_btn_save_preset->SetToolTip(format_wxstr(_L("Save current %s"), m_title));
m_btn_rename_preset->SetToolTip(from_u8((boost::format(_utf8(L("Rename current %s"))) % m_title).str())); // TRN Settings Tabs: Tooltip for rename button: "Settings"
m_btn_rename_preset->SetToolTip(format_wxstr(_L("Rename current %1%"), m_title));
m_btn_rename_preset->Hide(); m_btn_rename_preset->Hide();
m_btn_delete_preset->SetToolTip(_(L("Delete this preset"))); m_btn_delete_preset->SetToolTip(_(L("Delete this preset")));
m_btn_delete_preset->Hide(); m_btn_delete_preset->Hide();
@ -1602,6 +1603,8 @@ void TabPrint::build()
optgroup->append_single_option_line("wipe_tower_rotation_angle"); optgroup->append_single_option_line("wipe_tower_rotation_angle");
optgroup->append_single_option_line("wipe_tower_brim_width"); optgroup->append_single_option_line("wipe_tower_brim_width");
optgroup->append_single_option_line("wipe_tower_bridging"); optgroup->append_single_option_line("wipe_tower_bridging");
optgroup->append_single_option_line("wipe_tower_cone_angle");
optgroup->append_single_option_line("wipe_tower_extra_spacing");
optgroup->append_single_option_line("wipe_tower_no_sparse_layers"); optgroup->append_single_option_line("wipe_tower_no_sparse_layers");
optgroup->append_single_option_line("single_extruder_multi_material_priming"); optgroup->append_single_option_line("single_extruder_multi_material_priming");
@ -3922,8 +3925,7 @@ void Tab::delete_preset()
{ {
auto current_preset = m_presets->get_selected_preset(); auto current_preset = m_presets->get_selected_preset();
// Don't let the user delete the ' - default - ' configuration. // Don't let the user delete the ' - default - ' configuration.
std::string action = current_preset.is_external ? _utf8(L("remove")) : _utf8(L("delete")); wxString action = current_preset.is_external ? _L("remove") : _L("delete");
// TRN remove/delete
PhysicalPrinterCollection& physical_printers = m_preset_bundle->physical_printers; PhysicalPrinterCollection& physical_printers = m_preset_bundle->physical_printers;
wxString msg; wxString msg;
@ -3967,13 +3969,14 @@ void Tab::delete_preset()
"Note, that these printers will be deleted after deleting the selected preset.", ph_printers_only.size()) + "\n\n"; "Note, that these printers will be deleted after deleting the selected preset.", ph_printers_only.size()) + "\n\n";
} }
} }
// TRN "remove/delete"
msg += from_u8((boost::format(_u8L("Are you sure you want to %1% the selected preset?")) % action).str()); msg += from_u8((boost::format(_u8L("Are you sure you want to %1% the selected preset?")) % action).str());
} }
action = current_preset.is_external ? _utf8(L("Remove")) : _utf8(L("Delete")); action = current_preset.is_external ? _L("Remove") : _L("Delete");
// TRN Remove/Delete // TRN Settings Tabs: Button in toolbar: "Remove/Delete"
wxString title = from_u8((boost::format(_utf8(L("%1% Preset"))) % action).str()); //action + _(L(" Preset")); wxString title = format_wxstr(_L("%1% Preset"), action);
if (current_preset.is_default || if (current_preset.is_default ||
//wxID_YES != wxMessageDialog(parent(), msg, title, wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION).ShowModal()) //wxID_YES != wxMessageDialog(parent(), msg, title, wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION).ShowModal())
wxID_YES != MessageDialog(parent(), msg, title, wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION).ShowModal()) wxID_YES != MessageDialog(parent(), msg, title, wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION).ShowModal())
@ -4059,7 +4062,7 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep
deps.checkbox = new wxCheckBox(parent, wxID_ANY, _(L("All"))); deps.checkbox = new wxCheckBox(parent, wxID_ANY, _(L("All")));
deps.checkbox->SetFont(Slic3r::GUI::wxGetApp().normal_font()); deps.checkbox->SetFont(Slic3r::GUI::wxGetApp().normal_font());
wxGetApp().UpdateDarkUI(deps.checkbox, false, true); wxGetApp().UpdateDarkUI(deps.checkbox, false, true);
deps.btn = new ScalableButton(parent, wxID_ANY, "printer", from_u8((boost::format(" %s %s") % _utf8(L("Set")) % std::string(dots.ToUTF8())).str()), deps.btn = new ScalableButton(parent, wxID_ANY, "printer", format_wxstr(" %s %s", _L("Set"), dots),
wxDefaultSize, wxDefaultPosition, wxBU_LEFT | wxBU_EXACTFIT); wxDefaultSize, wxDefaultPosition, wxBU_LEFT | wxBU_EXACTFIT);
deps.btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); deps.btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
deps.btn->SetSize(deps.btn->GetBestSize()); deps.btn->SetSize(deps.btn->GetBestSize());
@ -5022,9 +5025,9 @@ void TabSLAPrint::update_description_lines()
{ {
bool elev = !m_config->opt_bool("pad_enable") || !m_config->opt_bool("pad_around_object"); bool elev = !m_config->opt_bool("pad_enable") || !m_config->opt_bool("pad_around_object");
m_support_object_elevation_description_line->SetText(elev ? "" : m_support_object_elevation_description_line->SetText(elev ? "" :
from_u8((boost::format(_u8L("\"%1%\" is disabled because \"%2%\" is on in \"%3%\" category.\n" format_wxstr(_L("\"%1%\" is disabled because \"%2%\" is on in \"%3%\" category.\n"
"To enable \"%1%\", please switch off \"%2%\"")) "To enable \"%1%\", please switch off \"%2%\"")
% _L("Object elevation") % _L("Pad around object") % _L("Pad")).str())); , _L("Object elevation"), _L("Pad around object"), _L("Pad")));
} }
} }
} }

View File

@ -1591,7 +1591,7 @@ void DiffPresetDialog::create_buttons()
} }
evt.Enable(enable); evt.Enable(enable);
}); });
m_transfer_btn->Bind(wxEVT_ENTER_WINDOW, [this, show_in_bottom_info](wxMouseEvent& e) { m_transfer_btn->Bind(wxEVT_ENTER_WINDOW, [show_in_bottom_info](wxMouseEvent& e) {
show_in_bottom_info(_L("Transfer the selected options from left preset to the right.\n" show_in_bottom_info(_L("Transfer the selected options from left preset to the right.\n"
"Note: New modified presets will be selected in settings tabs after close this dialog."), e); }); "Note: New modified presets will be selected in settings tabs after close this dialog."), e); });
@ -1599,7 +1599,7 @@ void DiffPresetDialog::create_buttons()
m_save_btn = new ScalableButton(this, wxID_ANY, "save", _L("Save"), wxDefaultSize, wxDefaultPosition, wxBORDER_DEFAULT, 24); m_save_btn = new ScalableButton(this, wxID_ANY, "save", _L("Save"), wxDefaultSize, wxDefaultPosition, wxBORDER_DEFAULT, 24);
m_save_btn->Bind(wxEVT_BUTTON, [this](wxEvent&) { button_event(Action::Save); }); m_save_btn->Bind(wxEVT_BUTTON, [this](wxEvent&) { button_event(Action::Save); });
m_save_btn->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(m_tree->has_selection()); }); m_save_btn->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(m_tree->has_selection()); });
m_save_btn->Bind(wxEVT_ENTER_WINDOW, [this, show_in_bottom_info](wxMouseEvent& e) { m_save_btn->Bind(wxEVT_ENTER_WINDOW, [show_in_bottom_info](wxMouseEvent& e) {
show_in_bottom_info(_L("Save the selected options from left preset to the right."), e); }); show_in_bottom_info(_L("Save the selected options from left preset to the right."), e); });
// Cancel // Cancel

View File

@ -135,10 +135,10 @@ bool AppUpdateAvailableDialog::disable_version_check() const
// AppUpdateDownloadDialog // AppUpdateDownloadDialog
AppUpdateDownloadDialog::AppUpdateDownloadDialog( const Semver& ver_online, boost::filesystem::path& path) AppUpdateDownloadDialog::AppUpdateDownloadDialog( const Semver& ver_online, boost::filesystem::path& path)
: MsgDialog(nullptr, _(L("App Update download")), wxString::Format(_(L("New version of %s is available.")), SLIC3R_APP_NAME)) : MsgDialog(nullptr, _L("App Update download"), format_wxstr(_L("New version of %1% is available."), SLIC3R_APP_NAME))
{ {
auto* versions = new wxFlexGridSizer(2, 0, VERT_SPACING); auto* versions = new wxFlexGridSizer(2, 0, VERT_SPACING);
versions->Add(new wxStaticText(this, wxID_ANY, _(L("New version:")))); versions->Add(new wxStaticText(this, wxID_ANY, _L("New version") + ":"));
versions->Add(new wxStaticText(this, wxID_ANY, ver_online.to_string())); versions->Add(new wxStaticText(this, wxID_ANY, ver_online.to_string()));
content_sizer->Add(versions); content_sizer->Add(versions);
content_sizer->AddSpacer(VERT_SPACING); content_sizer->AddSpacer(VERT_SPACING);
@ -148,7 +148,7 @@ AppUpdateDownloadDialog::AppUpdateDownloadDialog( const Semver& ver_online, boos
#endif #endif
content_sizer->AddSpacer(VERT_SPACING); content_sizer->AddSpacer(VERT_SPACING);
content_sizer->AddSpacer(VERT_SPACING); content_sizer->AddSpacer(VERT_SPACING);
content_sizer->Add(new wxStaticText(this, wxID_ANY, _(L("Target directory:")))); content_sizer->Add(new wxStaticText(this, wxID_ANY, _L("Target directory") + ":"));
content_sizer->AddSpacer(VERT_SPACING); content_sizer->AddSpacer(VERT_SPACING);
txtctrl_path = new wxTextCtrl(this, wxID_ANY, GUI::format_wxstr(path.parent_path().string())); txtctrl_path = new wxTextCtrl(this, wxID_ANY, GUI::format_wxstr(path.parent_path().string()));
filename = GUI::format_wxstr(path.filename().string()); filename = GUI::format_wxstr(path.filename().string());
@ -173,7 +173,7 @@ AppUpdateDownloadDialog::AppUpdateDownloadDialog( const Semver& ver_online, boos
dir = GUI::format(txtctrl_path->GetValue()); dir = GUI::format(txtctrl_path->GetValue());
wxDirDialog save_dlg( wxDirDialog save_dlg(
this this
, _L("Select directory:") , _L("Select directory") + ":"
, GUI::format_wxstr(dir.string()) , GUI::format_wxstr(dir.string())
/* /*
, filename //boost::nowide::widen(AppUpdater::get_filename_from_url(txtctrl_path->GetValue().ToUTF8().data())) , filename //boost::nowide::widen(AppUpdater::get_filename_from_url(txtctrl_path->GetValue().ToUTF8().data()))
@ -436,8 +436,7 @@ MsgDataIncompatible::~MsgDataIncompatible() {}
MsgDataLegacy::MsgDataLegacy() : MsgDataLegacy::MsgDataLegacy() :
MsgDialog(nullptr, _(L("Configuration update")), _(L("Configuration update"))) MsgDialog(nullptr, _(L("Configuration update")), _(L("Configuration update")))
{ {
auto *text = new wxStaticText(this, wxID_ANY, from_u8((boost::format( auto *text = new wxStaticText(this, wxID_ANY, format_wxstr( _L(
_utf8(L(
"%s now uses an updated configuration structure.\n\n" "%s now uses an updated configuration structure.\n\n"
"So called 'System presets' have been introduced, which hold the built-in default settings for various " "So called 'System presets' have been introduced, which hold the built-in default settings for various "
@ -447,10 +446,8 @@ MsgDataLegacy::MsgDataLegacy() :
"Please proceed with the %s that follows to set up the new presets " "Please proceed with the %s that follows to set up the new presets "
"and to choose whether to enable automatic preset updates." "and to choose whether to enable automatic preset updates."
))) )
% SLIC3R_APP_NAME , SLIC3R_APP_NAME, ConfigWizard::name()));
% _utf8(ConfigWizard::name())).str()
));
text->Wrap(CONTENT_WIDTH * wxGetApp().em_unit()); text->Wrap(CONTENT_WIDTH * wxGetApp().em_unit());
content_sizer->Add(text); content_sizer->Add(text);
content_sizer->AddSpacer(VERT_SPACING); content_sizer->AddSpacer(VERT_SPACING);
@ -458,7 +455,7 @@ MsgDataLegacy::MsgDataLegacy() :
auto *text2 = new wxStaticText(this, wxID_ANY, _(L("For more information please visit our wiki page:"))); auto *text2 = new wxStaticText(this, wxID_ANY, _(L("For more information please visit our wiki page:")));
static const wxString url("https://github.com/prusa3d/PrusaSlicer/wiki/Slic3r-PE-1.40-configuration-update"); static const wxString url("https://github.com/prusa3d/PrusaSlicer/wiki/Slic3r-PE-1.40-configuration-update");
// The wiki page name is intentionally not localized: // The wiki page name is intentionally not localized:
auto *link = new wxHyperlinkCtrl(this, wxID_ANY, wxString::Format("%s 1.40 configuration update", SLIC3R_APP_NAME), CONFIG_UPDATE_WIKI_URL); auto *link = new wxHyperlinkCtrl(this, wxID_ANY, format_wxstr(_L("%s 1.40 configuration update"), SLIC3R_APP_NAME), CONFIG_UPDATE_WIKI_URL);
content_sizer->Add(text2); content_sizer->Add(text2);
content_sizer->Add(link); content_sizer->Add(link);
content_sizer->AddSpacer(VERT_SPACING); content_sizer->AddSpacer(VERT_SPACING);

View File

@ -630,9 +630,8 @@ ModeButton::ModeButton( wxWindow* parent,
void ModeButton::Init(const wxString &mode) void ModeButton::Init(const wxString &mode)
{ {
std::string mode_str = std::string(mode.ToUTF8()); m_tt_focused = Slic3r::GUI::format_wxstr(_L("Switch to the %s mode"), mode);
m_tt_focused = Slic3r::GUI::from_u8((boost::format(_utf8(L("Switch to the %s mode"))) % mode_str).str()); m_tt_selected = Slic3r::GUI::format_wxstr(_L("Current mode is %s"), mode);
m_tt_selected = Slic3r::GUI::from_u8((boost::format(_utf8(L("Current mode is %s"))) % mode_str).str());
SetBitmapMargins(3, 0); SetBitmapMargins(3, 0);

View File

@ -39,7 +39,7 @@ namespace {
std::string msg; std::string msg;
bool res = GUI::create_process(path, std::wstring(), msg); bool res = GUI::create_process(path, std::wstring(), msg);
if (!res) { if (!res) {
std::string full_message = GUI::format(_utf8("Running downloaded instaler of %1% has failed:\n%2%"), SLIC3R_APP_NAME, msg); std::string full_message = GUI::format(_u8L("Running downloaded instaler of %1% has failed:\n%2%"), SLIC3R_APP_NAME, msg);
BOOST_LOG_TRIVIAL(error) << full_message; // lm: maybe UI error msg? // dk: bellow. (maybe some general show error evt would be better?) BOOST_LOG_TRIVIAL(error) << full_message; // lm: maybe UI error msg? // dk: bellow. (maybe some general show error evt would be better?)
wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_APP_DOWNLOAD_FAILED); wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_APP_DOWNLOAD_FAILED);
evt->SetString(full_message); evt->SetString(full_message);
@ -174,9 +174,7 @@ bool AppUpdater::priv::http_get_file(const std::string& url, size_t size_limit,
cancel = (m_cancel ? true : !progress_fn(std::move(progress))); cancel = (m_cancel ? true : !progress_fn(std::move(progress)));
if (cancel) { if (cancel) {
// Lets keep error_message empty here - if there is need to show error dialog, the message will be probably shown by whatever caused the cancel. // Lets keep error_message empty here - if there is need to show error dialog, the message will be probably shown by whatever caused the cancel.
/* //error_message = GUI::format(_u8L("Error getting: `%1%`: Download was canceled."), url);
error_message = GUI::format(_utf8("Error getting: `%1%`: Download was canceled."), url);
*/
BOOST_LOG_TRIVIAL(debug) << "AppUpdater::priv::http_get_file message: "<< error_message; BOOST_LOG_TRIVIAL(debug) << "AppUpdater::priv::http_get_file message: "<< error_message;
} }
}) })
@ -205,8 +203,8 @@ boost::filesystem::path AppUpdater::priv::download_file(const DownloadAppData& d
assert(!dest_path.empty()); assert(!dest_path.empty());
if (dest_path.empty()) if (dest_path.empty())
{ {
std::string line1 = GUI::format(_utf8("Internal download error for url %1%:"), data.url); std::string line1 = GUI::format(_u8L("Internal download error for url %1%:"), data.url);
std::string line2 = _utf8("Destination path is empty."); std::string line2 = _u8L("Destination path is empty.");
std::string message = GUI::format("%1%\n%2%", line1, line2); std::string message = GUI::format("%1%\n%2%", line1, line2);
BOOST_LOG_TRIVIAL(error) << message; BOOST_LOG_TRIVIAL(error) << message;
wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_APP_DOWNLOAD_FAILED); wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_APP_DOWNLOAD_FAILED);
@ -222,8 +220,8 @@ boost::filesystem::path AppUpdater::priv::download_file(const DownloadAppData& d
file = fopen(temp_path_wstring.c_str(), "wb"); file = fopen(temp_path_wstring.c_str(), "wb");
assert(file != NULL); assert(file != NULL);
if (file == NULL) { if (file == NULL) {
std::string line1 = GUI::format(_utf8("Download from %1% couldn't start:"), data.url); std::string line1 = GUI::format(_u8L("Download from %1% couldn't start:"), data.url);
std::string line2 = GUI::format(_utf8("Can't create file at %1%."), tmp_path.string()); std::string line2 = GUI::format(_u8L("Can't create file at %1%."), tmp_path.string());
std::string message = GUI::format("%1%\n%2%", line1, line2); std::string message = GUI::format("%1%\n%2%", line1, line2);
BOOST_LOG_TRIVIAL(error) << message; BOOST_LOG_TRIVIAL(error) << message;
wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_APP_DOWNLOAD_FAILED); wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_APP_DOWNLOAD_FAILED);
@ -264,11 +262,11 @@ boost::filesystem::path AppUpdater::priv::download_file(const DownloadAppData& d
// Size check. Does always 1 char == 1 byte? // Size check. Does always 1 char == 1 byte?
size_t body_size = body.size(); size_t body_size = body.size();
if (body_size != expected_size) { if (body_size != expected_size) {
error_message = GUI::format(_utf8("Downloaded file has wrong size. Expected size: %1% Downloaded size: %2%"), expected_size, body_size); error_message = GUI::format(_u8L("Downloaded file has wrong size. Expected size: %1% Downloaded size: %2%"), expected_size, body_size);
return false; return false;
} }
if (file == NULL) { if (file == NULL) {
error_message = GUI::format(_utf8("Can't create file at %1%."), tmp_path.string()); error_message = GUI::format(_u8L("Can't create file at %1%."), tmp_path.string());
return false; return false;
} }
try try
@ -279,7 +277,7 @@ boost::filesystem::path AppUpdater::priv::download_file(const DownloadAppData& d
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
error_message = GUI::format(_utf8("Failed to write to file or to move %1% to %2%:\n%3%"), tmp_path, dest_path, e.what()); error_message = GUI::format(_u8L("Failed to write to file or to move %1% to %2%:\n%3%"), tmp_path, dest_path, e.what());
return false; return false;
} }
return true; return true;
@ -295,7 +293,7 @@ boost::filesystem::path AppUpdater::priv::download_file(const DownloadAppData& d
} else { } else {
std::string message = (error_message.empty() std::string message = (error_message.empty()
? std::string() ? std::string()
: GUI::format(_utf8("Downloading new %1% has failed:\n%2%"), SLIC3R_APP_NAME, error_message)); : GUI::format(_u8L("Downloading new %1% has failed:\n%2%"), SLIC3R_APP_NAME, error_message));
wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_APP_DOWNLOAD_FAILED); wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_APP_DOWNLOAD_FAILED);
if (!message.empty()) { if (!message.empty()) {
BOOST_LOG_TRIVIAL(error) << message; BOOST_LOG_TRIVIAL(error) << message;

View File

@ -66,7 +66,7 @@ bool AstroBox::test(wxString &msg) const
const auto text = ptree.get_optional<std::string>("text"); const auto text = ptree.get_optional<std::string>("text");
res = validate_version_text(text); res = validate_version_text(text);
if (! res) { if (! res) {
msg = GUI::from_u8((boost::format(_utf8(L("Mismatched type of print host: %s"))) % (text ? *text : "AstroBox")).str()); msg = GUI::format_wxstr(_L("Mismatched type of print host: %s"), (text ? *text : "AstroBox"));
} }
} }
catch (const std::exception &) { catch (const std::exception &) {
@ -86,10 +86,10 @@ wxString AstroBox::get_test_ok_msg () const
wxString AstroBox::get_test_failed_msg (wxString &msg) const wxString AstroBox::get_test_failed_msg (wxString &msg) const
{ {
return GUI::from_u8((boost::format("%s: %s\n\n%s") return GUI::format_wxstr("%s: %s\n\n%s"
% _utf8(L("Could not connect to AstroBox")) , _L("Could not connect to AstroBox")
% std::string(msg.ToUTF8()) , msg
% _utf8(L("Note: AstroBox version at least 1.1.0 is required."))).str()); , _L("Note: AstroBox version at least 1.1.0 is required."));
} }
bool AstroBox::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn, InfoFn info_fn) const bool AstroBox::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn, InfoFn info_fn) const

View File

@ -49,9 +49,7 @@ wxString Duet::get_test_ok_msg () const
wxString Duet::get_test_failed_msg (wxString &msg) const wxString Duet::get_test_failed_msg (wxString &msg) const
{ {
return GUI::from_u8((boost::format("%s: %s") return GUI::format_wxstr("%s: %s", _L("Could not connect to Duet"), msg);
% _utf8(L("Could not connect to Duet"))
% std::string(msg.ToUTF8())).str());
} }
bool Duet::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn, InfoFn info_fn) const bool Duet::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn, InfoFn info_fn) const

View File

@ -70,10 +70,10 @@ wxString FlashAir::get_test_ok_msg () const
wxString FlashAir::get_test_failed_msg (wxString &msg) const wxString FlashAir::get_test_failed_msg (wxString &msg) const
{ {
return GUI::from_u8((boost::format("%s: %s\n%s") return GUI::format_wxstr("%s: %s\n%s"
% _utf8(L("Could not connect to FlashAir")) , _u8L("Could not connect to FlashAir")
% std::string(msg.ToUTF8()) , msg
% _utf8(L("Note: FlashAir with firmware 2.00.02 or newer and activated upload function is required."))).str()); , _u8L("Note: FlashAir with firmware 2.00.02 or newer and activated upload function is required."));
} }
bool FlashAir::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn, InfoFn info_fn) const bool FlashAir::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn, InfoFn info_fn) const

Some files were not shown because too many files have changed in this diff Show More