mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-27 02:41:17 +00:00
Update localizations and improve strings (#15739)
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user