mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-25 01:40:57 +00:00
Update localizations and improve strings (#15739)
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
#include "FilamentMixer.hpp"
|
||||
#include "LocalesUtils.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "format.hpp"
|
||||
#include "I18N.hpp"
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
@@ -82,8 +83,9 @@ bool check_filament_printable_after_group(const std::vector<unsigned int> &used_
|
||||
int printable_status = print_config->filament_printable.get_at(filament_id);
|
||||
int extruder_idx = filament_maps[filament_id];
|
||||
if (!(printable_status >> extruder_idx & 1)) {
|
||||
std::string extruder_name = extruder_idx == 0 ? _L("left") : _L("right");
|
||||
std::string error_msg = _L("Grouping error: ") + filament_type + _L(" can not be placed in the ") + extruder_name + _L(" nozzle");
|
||||
std::string error_msg = extruder_idx == 0 ?
|
||||
Slic3r::format(_L("Grouping error: %1% cannot be placed in the left nozzle"), filament_type) :
|
||||
Slic3r::format(_L("Grouping error: %1% cannot be placed in the right nozzle"), filament_type);
|
||||
throw Slic3r::RuntimeError(error_msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6302,6 +6302,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def = this->add("wipe_inward_distance", coFloatOrPercent);
|
||||
def->label = L("Wipe inward distance");
|
||||
def->category = L("Quality");
|
||||
// xgettext:no-c-format, no-boost-format
|
||||
def->tooltip = L("The distance the wipe path is shifted away from the external perimeter, specified in millimeters "
|
||||
"or as a percentage of the actual outer-wall extrusion width.\n\n"
|
||||
"For example, 50% shifts the path by half of the outer-wall width. The effective offset is limited "
|
||||
@@ -6762,7 +6763,7 @@ void PrintConfigDef::init_fff_params()
|
||||
|
||||
def = this->add("slicing_mode", coEnum);
|
||||
def->label = L("Slicing Mode");
|
||||
def->category = L("Other");
|
||||
def->category = L("Others");
|
||||
def->tooltip = L("Use \"Even-odd\" for 3DLabPrint airplane models. Use \"Close holes\" to close all holes in the model.");
|
||||
def->enum_keys_map = &ConfigOptionEnum<SlicingMode>::get_enum_values();
|
||||
def->enum_values.push_back("regular");
|
||||
|
||||
@@ -1197,11 +1197,11 @@ void AMSDryCtrWin::update_normal_description(DevAms* dev_ams)
|
||||
for (const auto& lim : ams_limits) {
|
||||
if (dev_ams->GetAmsType() == lim.type) {
|
||||
if (temp_val > lim.max_temp) {
|
||||
wxString msg = wxString(lim.name) + _L(" maximum drying temperature is ") + wxString::Format(wxT("%d"), lim.max_temp) + wxString::FromUTF8("°C.");
|
||||
wxString msg = wxString::Format(_L("%s maximum drying temperature is %d°C."), wxString(lim.name), lim.max_temp);
|
||||
warning_text += msg + "\n";
|
||||
can_enable_button = false;
|
||||
} else if (temp_val < lim.min_temp) {
|
||||
wxString msg = wxString(lim.name) + _L(" minimum drying temperature is ") + wxString::Format(wxT("%d"), lim.min_temp) + wxString::FromUTF8("°C.");
|
||||
wxString msg = wxString::Format(_L("%s minimum drying temperature is %d°C."), wxString(lim.name), lim.min_temp);
|
||||
warning_text += msg + "\n";
|
||||
can_enable_button = false;
|
||||
}
|
||||
|
||||
@@ -395,8 +395,9 @@ bool confirm_create_decompose_missing_components(wxWindow* parent, const std::ve
|
||||
missing_text += missing[i].display_name;
|
||||
}
|
||||
|
||||
wxString message = _L("The current filament list does not contain ") + missing_text +
|
||||
_L(". A project filament required by the mixed filament will be created automatically after decomposition.");
|
||||
wxString message = wxString::Format(_L("The current filament list does not contain %s. A project filament required by "
|
||||
"the mixed filament will be created automatically after decomposition."),
|
||||
missing_text);
|
||||
|
||||
MessageDialog dlg(parent, message, _L("Tip"), wxOK | wxCANCEL | wxICON_INFORMATION);
|
||||
dlg.show_dsa_button();
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "Plater.hpp"
|
||||
#include "Camera.hpp"
|
||||
#include "I18N.hpp"
|
||||
#include "format.hpp"
|
||||
#include "GUI_Utils.hpp"
|
||||
#include "GUI.hpp"
|
||||
#include "GLCanvas3D.hpp"
|
||||
@@ -3436,16 +3437,18 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
||||
return ret;
|
||||
};
|
||||
|
||||
// Whole sentences: the bare "up to"/"above"/"from"/"to" these used to be glued from gave a
|
||||
// translator no context, and left the unit and the numbers stuck in English word order.
|
||||
auto upto_label = [](double z) {
|
||||
char buf[64];
|
||||
::sprintf(buf, "%.2f", z);
|
||||
return _u8L("up to") + " " + std::string(buf) + " " + _u8L("mm");
|
||||
return format(_u8L("up to %1% mm"), buf);
|
||||
};
|
||||
|
||||
auto above_label = [](double z) {
|
||||
char buf[64];
|
||||
::sprintf(buf, "%.2f", z);
|
||||
return _u8L("above") + " " + std::string(buf) + " " + _u8L("mm");
|
||||
return format(_u8L("above %1% mm"), buf);
|
||||
};
|
||||
|
||||
auto fromto_label = [](double z1, double z2) {
|
||||
@@ -3453,7 +3456,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
||||
::sprintf(buf1, "%.2f", z1);
|
||||
char buf2[64];
|
||||
::sprintf(buf2, "%.2f", z2);
|
||||
return _u8L("from") + " " + std::string(buf1) + " " + _u8L("to") + " " + std::string(buf2) + " " + _u8L("mm");
|
||||
return format(_u8L("from %1% to %2% mm"), buf1, buf2);
|
||||
};
|
||||
|
||||
auto role_time_and_percent = [this, total_estimated_time](libvgcode::EGCodeExtrusionRole role) {
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <wx/dcmemory.h>
|
||||
#include <wx/dcgraph.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/wrapsizer.h>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
@@ -416,12 +417,54 @@ std::set<size_t> project_used_filament_slots(const PresetBundle& bundle, const D
|
||||
return used;
|
||||
}
|
||||
|
||||
// Lays a translated sentence out along `row`, replacing each "%1%"-style placeholder with the
|
||||
// matching window from `chips`. Keeping the sentence in one msgid lets a translation put the
|
||||
// placeholders wherever its own grammar needs them; spacing comes from the translation itself.
|
||||
void add_sentence_with_chips(wxWindow* parent, wxSizer* row, const wxString& sentence, const std::vector<wxWindow*>& chips)
|
||||
{
|
||||
std::vector<bool> placed(chips.size(), false);
|
||||
auto add_text = [&](wxString text) {
|
||||
text.Replace("%%", "%"); // the sentence is a format string
|
||||
if (text.IsEmpty())
|
||||
return;
|
||||
auto* label = new wxStaticText(parent, wxID_ANY, text);
|
||||
label->SetFont(Label::Body_12);
|
||||
label->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#6B6B6B")));
|
||||
row->Add(label, 0, wxALIGN_CENTER_VERTICAL);
|
||||
};
|
||||
auto add_chip = [&](size_t i) {
|
||||
if (i < chips.size() && chips[i] != nullptr && !placed[i]) {
|
||||
placed[i] = true;
|
||||
row->Add(chips[i], 0, wxALIGN_CENTER_VERTICAL);
|
||||
}
|
||||
};
|
||||
|
||||
size_t literal = 0, pos = 0;
|
||||
while ((pos = sentence.find('%', pos)) != wxString::npos) {
|
||||
size_t end = pos + 1;
|
||||
while (end < sentence.length() && sentence[end] >= '0' && sentence[end] <= '9')
|
||||
++end;
|
||||
if (end == pos + 1 || end >= sentence.length() || sentence[end] != '%') {
|
||||
++pos; // a bare '%'
|
||||
continue;
|
||||
}
|
||||
long index = 0;
|
||||
sentence.Mid(pos + 1, end - pos - 1).ToLong(&index);
|
||||
add_text(sentence.Mid(literal, pos - literal));
|
||||
add_chip(size_t(index - 1));
|
||||
literal = pos = end + 1;
|
||||
}
|
||||
add_text(sentence.Mid(literal));
|
||||
for (size_t i = 0; i < chips.size(); ++i) // whatever the translation left out
|
||||
add_chip(i);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Warning shown on OK when an enabled mixed-filament slot relies on a filament that would ship
|
||||
// without its material. One row per unmet dependency: the mixed slot's colour chip, the
|
||||
// component filament's colour chip, and the reason. "Cancel" is the safe choice and keeps the
|
||||
// dialog open; "Publish anyway" continues.
|
||||
// without its material. One row per unmet dependency, each a single translated sentence whose
|
||||
// two placeholders are the mixed slot's and the component filament's colour chips. "Cancel" is
|
||||
// the safe choice and keeps the dialog open; "Publish anyway" continues.
|
||||
class MixedFilamentWarningDialog : public MsgDialog
|
||||
{
|
||||
public:
|
||||
@@ -437,47 +480,37 @@ public:
|
||||
content->AddSpacer(FromDIP(10));
|
||||
|
||||
const int swatch = FromDIP(20);
|
||||
for (const MixedDependencyIssue& issue : issues) {
|
||||
auto* row = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
// The mixed slot as just its own chip (gradient-aware, numbered like its tab);
|
||||
// falls back to a plain label when the chip cannot be built.
|
||||
const wxString mix_label = wxString::Format(_L("Filament %d (mixed)"), int(issue.mixed_slot) + 1);
|
||||
const wxBitmap mix_bmp = mixed_filament_chip_bitmap(full, issue.mixed_slot, swatch);
|
||||
if (mix_bmp.IsOk()) {
|
||||
auto* bmp = new wxStaticBitmap(this, wxID_ANY, mix_bmp);
|
||||
bmp->SetToolTip(mix_label);
|
||||
row->Add(bmp, 0, wxALIGN_CENTER_VERTICAL);
|
||||
} else {
|
||||
auto* label = new wxStaticText(this, wxID_ANY, mix_label);
|
||||
label->SetFont(Label::Body_12);
|
||||
row->Add(label, 0, wxALIGN_CENTER_VERTICAL);
|
||||
// The slot's colour swatch, numbered like its tab, with the slot name on hover; falls
|
||||
// back to a label so the sentence always names both filaments.
|
||||
auto make_chip = [&](const wxBitmap& bmp, const wxString& name) -> wxWindow* {
|
||||
if (bmp.IsOk()) {
|
||||
auto* chip = new wxStaticBitmap(this, wxID_ANY, bmp);
|
||||
chip->SetToolTip(name);
|
||||
return chip;
|
||||
}
|
||||
auto* label = new wxStaticText(this, wxID_ANY, name);
|
||||
label->SetFont(Label::Body_12);
|
||||
return label;
|
||||
};
|
||||
|
||||
auto* needs = new wxStaticText(this, wxID_ANY, _L("needs"));
|
||||
needs->SetFont(Label::Body_12);
|
||||
needs->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#6B6B6B")));
|
||||
row->Add(needs, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, FromDIP(6));
|
||||
|
||||
// The component filament's colour chip, numbered like the tab strips; the slot
|
||||
// name stays on hover to keep the row itself short.
|
||||
for (const MixedDependencyIssue& issue : issues) {
|
||||
std::string hex = filament_color_hex(full, issue.component_slot);
|
||||
if (hex.empty())
|
||||
hex = "#D9D9D9";
|
||||
if (wxBitmap* chip = get_extruder_color_icon(hex, std::to_string(issue.component_slot + 1), swatch, swatch)) {
|
||||
auto* comp_bmp = new wxStaticBitmap(this, wxID_ANY, *chip);
|
||||
comp_bmp->SetToolTip(wxString::Format(_L("Filament %d"), int(issue.component_slot) + 1));
|
||||
row->Add(comp_bmp, 0, wxALIGN_CENTER_VERTICAL);
|
||||
}
|
||||
const wxBitmap* comp_bmp = get_extruder_color_icon(hex, std::to_string(issue.component_slot + 1), swatch, swatch);
|
||||
|
||||
auto* reason = new wxStaticText(this, wxID_ANY,
|
||||
issue.reason == MixedDependencyIssue::Reason::Disabled ? _L("not enabled") :
|
||||
_L("material not published"));
|
||||
reason->SetFont(Label::Body_12);
|
||||
reason->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#989898")));
|
||||
row->Add(reason, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(8));
|
||||
wxWindow* mix_chip = make_chip(mixed_filament_chip_bitmap(full, issue.mixed_slot, swatch),
|
||||
wxString::Format(_L("Filament %d (mixed)"), int(issue.mixed_slot) + 1));
|
||||
wxWindow* comp_chip = make_chip(comp_bmp != nullptr ? *comp_bmp : wxNullBitmap,
|
||||
wxString::Format(_L("Filament %d"), int(issue.component_slot) + 1));
|
||||
|
||||
content->Add(row, 0, wxLEFT, FromDIP(10));
|
||||
auto* row = new wxWrapSizer(wxHORIZONTAL);
|
||||
add_sentence_with_chips(this, row,
|
||||
issue.reason == MixedDependencyIssue::Reason::Disabled ?
|
||||
_L("%1% needs %2%, which is not enabled.") :
|
||||
_L("%1% needs %2%, whose material will not be published."),
|
||||
{mix_chip, comp_chip});
|
||||
content->Add(row, 0, wxEXPAND | wxLEFT, FromDIP(10));
|
||||
content->AddSpacer(FromDIP(6));
|
||||
}
|
||||
|
||||
|
||||
@@ -1497,7 +1497,7 @@ void UnsavedChangesDialog::update_tree(Preset::Type type, DynamicConfig * config
|
||||
const std::string label = def ? (def->full_label.empty() ? def->label : def->full_label) : std::string();
|
||||
option.label_local = (label.empty() ? from_u8(opt_key) : _L(label)).ToStdWstring();
|
||||
option.category_local = (def && !def->category.empty() ?
|
||||
Tab::translate_category(from_u8(def->category), type) : _L("Other")).ToStdWstring();
|
||||
Tab::translate_category(from_u8(def->category), type) : _L("Others")).ToStdWstring();
|
||||
}
|
||||
auto category = option.category_local;
|
||||
auto opt = dynamic_cast<ConfigOptionVectorBase*>(config->option(opt_key));
|
||||
|
||||
@@ -275,9 +275,9 @@ void TempInput::Warning(bool warn, WarningType type)
|
||||
|
||||
wxString warning_string;
|
||||
if (type == WarningType::WARNING_TOO_HIGH)
|
||||
warning_string = _L("The maximum temperature cannot exceed ") + wxString::Format("%d", max_temp);
|
||||
warning_string = wxString::Format(_L("The maximum temperature cannot exceed %d"), max_temp);
|
||||
else if (type == WarningType::WARNING_TOO_LOW)
|
||||
warning_string = _L("The minmum temperature should not be less than ") + wxString::Format("%d", min_temp);
|
||||
warning_string = wxString::Format(_L("The minimum temperature should not be less than %d"), min_temp);
|
||||
warning_text->SetLabel(warning_string);
|
||||
warning_text->Wrap(-1);
|
||||
warning_text->Fit();
|
||||
|
||||
@@ -1711,7 +1711,7 @@ void PresetUpdater::priv::check_new_vendors(const std::set<std::string>& system_
|
||||
GUI::wxGetApp().plater()->get_notification_manager()->push_notification(
|
||||
GUI::NotificationType::PresetUpdateFinished,
|
||||
GUI::NotificationManager::NotificationLevel::ImportantNotificationLevel,
|
||||
_u8L("Configuration package: ") + vendor_id + _u8L(" updated to ") + cur_ver.to_string());
|
||||
Slic3r::format(_u8L("Configuration package: %1% updated to %2%"), vendor_id, cur_ver.to_string()));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1806,7 +1806,7 @@ PresetUpdater::UpdateResult PresetUpdater::config_update(const Semver& old_slic3
|
||||
->get_notification_manager()
|
||||
->push_notification(GUI::NotificationType::PresetUpdateFinished,
|
||||
GUI::NotificationManager::NotificationLevel::ImportantNotificationLevel,
|
||||
_u8L("Configuration package: ") + b + _u8L(" updated to ") + cur_ver.to_string());
|
||||
Slic3r::format(_u8L("Configuration package: %1% updated to %2%"), b, cur_ver.to_string()));
|
||||
}
|
||||
return R_UPDATE_INSTALLED;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user