From 5eac300d91a284b37e0bef7cec7e8c14995de5c4 Mon Sep 17 00:00:00 2001 From: Clifford Garwood Date: Thu, 3 Sep 2026 10:05:37 -0400 Subject: [PATCH] Use IDEX/IQEX in the user-facing strings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes review comment 10. `461c69c83e` settled this in April — IMEX internally, IDEX/IQEX as the user-facing label — but the UI strings were never converted. Every translated string naming the feature now reads IDEX/IQEX: 41 occurrences across the printer and process option labels and tooltips, the modes editor, the plate mode indicator, the pre-slice warnings, the placement refusals and the slicing errors. The reviewer listed eight; the rest were in the same class. Nothing else moves. The config keys keep the `imex_` spelling — `is_imex`, `imex_mode_names`, `imex_parallel_mode` and the rest are on-disk format in existing printer presets and 3MF projects, so renaming them would break every profile and project already saved. C++ identifiers, filenames, comments and test names keep IMEX as well: it stays the internal name of the subsystem, which is what covers the topology space (one gantry with 2-4 tools, 2x1 and 2x2 grids) that neither acronym names on its own. Where a tooltip quotes a key, the key spelling is preserved and only the feature word around it changed. The `is_imex` tooltip is reworded rather than substituted: it already named the hardware families parenthetically, so a literal replacement would have said IDEX/IQEX twice in one sentence. No translation impact — no IMEX string had reached OrcaSlicer.pot or any catalogue, so there is nothing to migrate. One test asserted on the old error text and now matches the new one. Co-Authored-By: Claude Opus 5 (1M context) --- src/libslic3r/GCode.cpp | 8 +++--- src/libslic3r/Print.cpp | 4 +-- src/libslic3r/PrintConfig.cpp | 34 +++++++++++++------------- src/slic3r/GUI/IMEXModesCtrl.cpp | 4 +-- src/slic3r/GUI/MainFrame.cpp | 4 +-- src/slic3r/GUI/PartPlate.cpp | 4 +-- src/slic3r/GUI/Plater.cpp | 12 ++++----- src/slic3r/GUI/Tab.cpp | 6 ++--- tests/fff_print/test_multifilament.cpp | 2 +- 9 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 58d681890c..e28402c155 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3731,13 +3731,13 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato print.active_step_add_warning( PrintStateBase::WarningLevel::NON_CRITICAL, imex_mode_resolved - ? Slic3r::format(_(L("The IMEX mode \"%1%\" has no tools assigned on the selected printer. " + ? Slic3r::format(_(L("The IDEX/IQEX mode \"%1%\" has no tools assigned on the selected printer. " "Printing in Primary mode instead. Assign the mode's tools in Printer " - "Settings, or pick another mode from the plate's IMEX button.")), + "Settings, or pick another mode from the plate's IDEX/IQEX button.")), imex_active_mode) - : Slic3r::format(_(L("This plate is set to the IMEX mode \"%1%\", which the selected printer " + : Slic3r::format(_(L("This plate is set to the IDEX/IQEX mode \"%1%\", which the selected printer " "does not define. Printing in Primary mode instead. Pick a mode from the " - "plate's IMEX button, or restore the mode in Printer Settings.")), + "plate's IDEX/IQEX button, or restore the mode in Printer Settings.")), imex_active_mode)); imex_active_mode = kImexPrimaryMode; imex_active_mode_index = 0; diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 6a0c8eefec..c32cde9eb9 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1377,7 +1377,7 @@ StringObjectException Print::validate(std::vector *warnin StringObjectException err; // "Mixed filament" is the term the rest of the UI uses -- the button that // creates one, and the sibling refusal for the wipe tower filament. - err.string = L("Mixed filaments are not supported in IMEX parallel modes. " + err.string = L("Mixed filaments are not supported in IDEX/IQEX parallel modes. " "Switch this plate to Primary mode."); err.object = m_objects.front(); return err; @@ -1442,7 +1442,7 @@ StringObjectException Print::validate(std::vector *warnin StringObjectException err; err.string = Slic3r::format( - L("IMEX mode \"%1%\" prints with T%2%, but this plate's filaments are on %3%. " + L("IDEX/IQEX mode \"%1%\" prints with T%2%, but this plate's filaments are on %3%. " "Assign a filament loaded on T%2%, or switch this plate to Primary mode."), parallel_mode, routing.primary_phys, routed_list); // Gives the notification a "Jump to " link, which selects the object diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index fc946211a5..fd7bad0945 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -6611,8 +6611,8 @@ void PrintConfigDef::init_fff_params() // g-code. They all carry non-nil defaults, so emitting them would add a line to every // printer's dump. Kept out of the g-code config block (banned_keys). def = this->add("is_imex", coBool); - def->label = L("IMEX Printer"); - def->tooltip = L("Enable IMEX parallel printing for printers with multiple independent carriages (IDEX, IQEX, and similar)."); + def->label = L("IDEX/IQEX Printer"); + def->tooltip = L("Enable parallel printing for printers with multiple independent carriages (IDEX, IQEX, and similar)."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(false)); @@ -6693,7 +6693,7 @@ void PrintConfigDef::init_fff_params() def = this->add("imex_viz_theme", coEnum); def->label = L("Visualization Theme"); - def->tooltip = L("Color theme for IMEX bed zone visualization. Choose a colorblind-friendly theme if needed."); + def->tooltip = L("Color theme for IDEX/IQEX bed zone visualization. Choose a colorblind-friendly theme if needed."); def->mode = comAdvanced; def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); def->enum_values.push_back("standard"); @@ -6707,32 +6707,32 @@ void PrintConfigDef::init_fff_params() def->set_default_value(new ConfigOptionEnum(ImexVizTheme::Standard)); def = this->add("imex_parallel_mode", coString); - def->label = L("IMEX Print Mode"); - def->tooltip = L("Name of the active IMEX parallel print mode, or \"primary\" for single-carriage printing. Requires IMEX Printer enabled in the Printer preset (Printer \u2192 Multimaterial \u2192 IMEX Configuration)."); + def->label = L("IDEX/IQEX Print Mode"); + def->tooltip = L("Name of the active IDEX/IQEX parallel print mode, or \"primary\" for single-carriage printing. Requires IDEX/IQEX Printer enabled in the Printer preset (Printer \u2192 Multimaterial \u2192 IDEX/IQEX Configuration)."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionString("primary")); def = this->add("imex_head_filament_map", coString); - def->label = L("IMEX head filament map"); + def->label = L("IDEX/IQEX head filament map"); def->tooltip = L("Per-plate override mapping physical heads to filament slots " "(1-based). Empty means use pem-inversion defaults."); def->mode = comDevelop; def->set_default_value(new ConfigOptionString("")); def = this->add("imex_mode_names", coStrings); - def->label = L("IMEX Mode Names"); - def->tooltip = L("Display names for each user-defined IMEX parallel print mode."); + def->label = L("IDEX/IQEX Mode Names"); + def->tooltip = L("Display names for each user-defined IDEX/IQEX parallel print mode."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionStrings()); def = this->add("imex_mode_active_tools", coStrings); - def->label = L("IMEX Mode Active Tools"); - def->tooltip = L("Tool role assignments for each mode. Format: \"idx:P,idx:C,idx:M\" where P=Primary, C=Copy, M=Mirror (e.g. \"0:P,1:C,2:M,3:M\"). Managed by the IMEX Modes editor in the Printer preset."); + def->label = L("IDEX/IQEX Mode Active Tools"); + def->tooltip = L("Tool role assignments for each mode. Format: \"idx:P,idx:C,idx:M\" where P=Primary, C=Copy, M=Mirror (e.g. \"0:P,1:C,2:M,3:M\"). Managed by the IDEX/IQEX Modes editor in the Printer preset."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionStrings()); def = this->add("imex_mode_gcodes", coStrings); - def->label = L("IMEX Mode G-codes"); + def->label = L("IDEX/IQEX Mode G-codes"); def->tooltip = L("G-code or macro call to inject at print start for each mode."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionStrings()); @@ -12629,16 +12629,16 @@ OtherSlicingStatesConfigDef::OtherSlicingStatesConfigDef() new_def("in_head_wrap_detect_zone", coBool, "In head wrap detect zone", "Indicates if the first layer overlaps with the head wrap zone."); def = this->add("imex_mode", coString); - def->label = L("IMEX active mode"); - def->tooltip = L("Name of the active IMEX parallel print mode for this plate (e.g. 'primary', 'mirror', 'copy'). Empty string if IMEX is not enabled."); + def->label = L("IDEX/IQEX active mode"); + def->tooltip = L("Name of the active IDEX/IQEX parallel print mode for this plate (e.g. 'primary', 'mirror', 'copy'). Empty string if IDEX/IQEX is not enabled."); def = this->add("imex_mode_index", coInt); - def->label = L("IMEX active mode index"); - def->tooltip = L("Zero-based index of the active IMEX parallel print mode within imex_mode_names."); + def->label = L("IDEX/IQEX active mode index"); + def->tooltip = L("Zero-based index of the active IDEX/IQEX parallel print mode within imex_mode_names."); def = this->add("imex_mode_gcode", coString); - def->label = L("IMEX active mode G-code"); - def->tooltip = L("The raw mode G-code template for the active IMEX parallel print mode, after placeholder evaluation. Globals defined here flow into machine_start_gcode."); + def->label = L("IDEX/IQEX active mode G-code"); + def->tooltip = L("The raw mode G-code template for the active IDEX/IQEX parallel print mode, after placeholder evaluation. Globals defined here flow into machine_start_gcode."); } PrintStatisticsConfigDef::PrintStatisticsConfigDef() diff --git a/src/slic3r/GUI/IMEXModesCtrl.cpp b/src/slic3r/GUI/IMEXModesCtrl.cpp index f1a3570e97..a07d95191c 100644 --- a/src/slic3r/GUI/IMEXModesCtrl.cpp +++ b/src/slic3r/GUI/IMEXModesCtrl.cpp @@ -104,7 +104,7 @@ void IMEXModesCtrl::rebuild_info_and_header() { auto* hdr_name = new wxStaticText(m_hdr_panel, wxID_ANY, _L("Name")); auto* hdr_tools = new wxStaticText(m_hdr_panel, wxID_ANY, _L("Tools")); auto* hdr_gcode = new wxStaticText(m_hdr_panel, wxID_ANY, _L("G-code")); - hdr_name->SetToolTip(_L("How the mode is labelled in the plate's IMEX mode selector. " + hdr_name->SetToolTip(_L("How the mode is labelled in the plate's IDEX/IQEX mode selector. " "Required — a mode with no name cannot be selected.")); hdr_tools->SetToolTip(_L("Which tool heads take part in the mode and what role each one plays. " "Click a tile to cycle its role.")); @@ -368,7 +368,7 @@ void IMEXModesCtrl::add_row(const std::string& name, r.orig_name = nm; r.name = new wxTextCtrl(r.panel, wxID_ANY, from_u8(nm), wxDefaultPosition, FromDIP(wxSize(130, -1))); r.name->SetHint(_L("Mode name (required)")); - r.name->SetToolTip(_L("Name of this parallel mode, as it appears in the plate's IMEX mode " + r.name->SetToolTip(_L("Name of this parallel mode, as it appears in the plate's IDEX/IQEX mode " "selector. Stored in the project by name, so renaming a mode that " "plates already use makes them fall back to Primary. Cannot be empty " "— a blank name is replaced with a generated one.")); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 7f0001be4e..a2b6c9d7a5 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -3190,8 +3190,8 @@ void MainFrame::init_menubar_as_editor() // change adds true toolhead model support (cf. printer bed models) this same toggle // governs that. Only relevant on Preview, and only meaningful when the active // printer is IDEX/IQEX — gated to keep the menu uncluttered for everyone else. - append_menu_check_item(viewMenu, wxID_ANY, _L("Show IMEX Toolhead"), - _L("Show the IMEX toolhead representation around each active nozzle in the G-code preview."), + append_menu_check_item(viewMenu, wxID_ANY, _L("Show IDEX/IQEX Toolhead"), + _L("Show the IDEX/IQEX toolhead representation around each active nozzle in the G-code preview."), [this](wxCommandEvent&) { const bool current = wxGetApp().app_config->get("show_imex_toolhead_boxes") != "false"; wxGetApp().app_config->set("show_imex_toolhead_boxes", current ? "false" : "true"); diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index a828936ed0..b32c438b9b 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -2127,7 +2127,7 @@ void PartPlate::render_icons(bool bottom, bool only_name, int hover_id) render_icon_texture(m_imex_mode_icon.model, m_partplate_list->m_imex_mode_hovered_texture); std::string cur = get_imex_mode(); if (cur == kImexPrimaryMode) cur = _u8L("Primary"); - show_tooltip(_u8L("IMEX mode: ") + cur + _u8L(" (left-click to cycle, right-click for menu)")); + show_tooltip(_u8L("IDEX/IQEX mode: ") + cur + _u8L(" (left-click to cycle, right-click for menu)")); } else { render_icon_texture(m_imex_mode_icon.model, m_partplate_list->m_imex_mode_texture); } @@ -2135,7 +2135,7 @@ void PartPlate::render_icons(bool bottom, bool only_name, int hover_id) if (has_imex_multimaterial_conflict()) { render_icon_texture(m_imex_warn_icon, m_partplate_list->m_imex_warn_texture); if (hover_id == (int)PLATE_IMEX_MODE_ID) - show_tooltip(_u8L("Warning: this plate uses a parallel IMEX mode with multi-material objects. Proceed with caution — verify your G-code handles this combination correctly.")); + show_tooltip(_u8L("Warning: this plate uses a parallel IDEX/IQEX mode with multi-material objects. Proceed with caution — verify your G-code handles this combination correctly.")); } } } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 0d1360b37c..aa0a5f14a6 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -10457,10 +10457,10 @@ std::string imex_placement_error(PartPlate* plate) return {}; switch (plate->imex_placement_violation()) { case PartPlate::ImexPlacementViolation::Object: - return _u8L("Cannot slice: an object overlaps an area reserved for IMEX parallel printing " + return _u8L("Cannot slice: an object overlaps an area reserved for IDEX/IQEX parallel printing " "(a secondary zone, or a carriage clearance strip inside the primary zone)."); case PartPlate::ImexPlacementViolation::PrimeTower: - return _u8L("Cannot slice: the prime tower overlaps an area reserved for IMEX parallel printing " + return _u8L("Cannot slice: the prime tower overlaps an area reserved for IDEX/IQEX parallel printing " "(a secondary zone, or a carriage clearance strip inside the primary zone)."); case PartPlate::ImexPlacementViolation::None: break; @@ -12843,11 +12843,11 @@ void Plater::priv::on_action_slice_plate(SimpleEvent&) std::vector warnings = collect_imex_warnings(plate); if (!warnings.empty()) { int plate_num = partplate_list.get_curr_plate_index() + 1; - wxString msg = wxString::Format(_L("Plate %d has IMEX parallel mode active with the following concerns:\n\n"), plate_num); + wxString msg = wxString::Format(_L("Plate %d has IDEX/IQEX parallel mode active with the following concerns:\n\n"), plate_num); for (const wxString& w : warnings) msg += L"\u2022 " + w + "\n\n"; msg += _L("Continue slicing?"); - RichMessageDialog dlg(q, msg, _L("IMEX Parallel Mode Warning"), wxICON_WARNING | wxYES | wxNO); + RichMessageDialog dlg(q, msg, _L("IDEX/IQEX Parallel Mode Warning"), wxICON_WARNING | wxYES | wxNO); dlg.ShowCheckBox(_L("Don't show these warnings again")); int result = dlg.ShowModal(); if (dlg.IsCheckBoxChecked()) @@ -12892,10 +12892,10 @@ void Plater::priv::on_action_slice_all(SimpleEvent&) combined_msg += "\n"; } if (!combined_msg.empty()) { - wxString msg = _L("The following IMEX parallel mode concerns were detected:\n\n") + wxString msg = _L("The following IDEX/IQEX parallel mode concerns were detected:\n\n") + combined_msg + _L("Continue slicing?"); - RichMessageDialog dlg(q, msg, _L("IMEX Parallel Mode Warning"), wxICON_WARNING | wxYES | wxNO); + RichMessageDialog dlg(q, msg, _L("IDEX/IQEX Parallel Mode Warning"), wxICON_WARNING | wxYES | wxNO); dlg.ShowCheckBox(_L("Don't show these warnings again")); int result = dlg.ShowModal(); if (dlg.IsCheckBoxChecked()) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 62e133a53f..f952223a71 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -5636,7 +5636,7 @@ if (is_marlin_flavor) optgroup->append_single_option_line("machine_tool_change_time", "printer_multimaterial_advanced#tool-change-time"); // IDEX/IQEX (IMEX) parallel printing configuration - optgroup = page->new_optgroup(L("IMEX Configuration"), L"param_advanced"); + optgroup = page->new_optgroup(L("IDEX/IQEX Configuration"), L"param_advanced"); optgroup->append_single_option_line("is_imex"); optgroup->append_single_option_line("imex_firmware_managed_zones"); optgroup->append_single_option_line("imex_gantry_count"); @@ -5657,7 +5657,7 @@ if (is_marlin_flavor) // activate_line to return early before build_field. ConfigOptionDef placeholder_def; placeholder_def.label = L("Pre-slice warnings"); - placeholder_def.tooltip = L("Show a warning dialog before slicing if IMEX parallel mode " + placeholder_def.tooltip = L("Show a warning dialog before slicing if IDEX/IQEX parallel mode " "concerns are detected (bed temperature conflicts, filament type " "mismatches, multi-material conflicts). Can be suppressed from the " "dialog itself. Re-enable here if suppressed accidentally."); @@ -5678,7 +5678,7 @@ if (is_marlin_flavor) } optgroup->append_single_option_line("imex_viz_theme"); { - auto modes_og = page->new_optgroup(L("IMEX Parallel Modes"), L"param_advanced"); + auto modes_og = page->new_optgroup(L("IDEX/IQEX Parallel Modes"), L"param_advanced"); auto line = Line{ L("Modes"), L("") }; line.full_width = 1; line.widget = [this](wxWindow* parent) -> wxSizer* { diff --git a/tests/fff_print/test_multifilament.cpp b/tests/fff_print/test_multifilament.cpp index 05d5993c07..a871af5aa9 100644 --- a/tests/fff_print/test_multifilament.cpp +++ b/tests/fff_print/test_multifilament.cpp @@ -1246,7 +1246,7 @@ TEST_CASE("A mixed filament outranks the multi-color rule on the same plate", Slic3r::Print print; const StringObjectException err = validate_plate(build(true), print, model); REQUIRE_FALSE(err.string.empty()); - CHECK(err.string.find("not supported in IMEX parallel modes") != std::string::npos); + CHECK(err.string.find("not supported in IDEX/IQEX parallel modes") != std::string::npos); CHECK(err.string.find("Multi-color") == std::string::npos); // The two rules differ in more than wording: the mixed path attaches an object (for the // notification's "Jump to" link), the multi-color path returns none. Pins which fired