Merge branch 'main' into fix/plugin-bugs

This commit is contained in:
Ian Chua
2026-07-21 12:56:52 +08:00
committed by GitHub
54 changed files with 12181 additions and 5395 deletions
+4 -4
View File
@@ -454,7 +454,7 @@ wxBoxSizer* AMSDryCtrWin::create_normal_state_panel(wxPanel* parent)
m_temperature_input->SetBackgroundColour(StateColor::darkModeColorFor(*wxWHITE));
m_temperature_input->SetForegroundColour(StateColor::darkModeColorFor(*wxBLACK));
Label* temp_unit_label = new Label(parent, wxString::FromUTF8("℃"));
Label* temp_unit_label = new Label(parent, wxString::FromUTF8(u8"\u2103" /* °C */));
temp_unit_label->SetForegroundColour(*wxBLACK);
temp_sizer->Add(m_temperature_input, 1, wxRIGHT, FromDIP(1));
temp_sizer->Add(temp_unit_label, 0, wxALIGN_CENTER_VERTICAL);
@@ -1444,9 +1444,9 @@ int AMSDryCtrWin::update_ams_change(DevAms* dev_ams)
m_ams_info.m_ams_id = dev_ams->GetAmsId();
if (dev_ams->GetAmsType() == DevAmsType::N3F) {
m_temperature_input->SetHint("45-65" + wxString::FromUTF8("°C"));
m_temperature_input->SetHint("45-65" + wxString::FromUTF8(u8"\u2103" /* °C */));
} else if (dev_ams->GetAmsType() == DevAmsType::N3S) {
m_temperature_input->SetHint("45-85" + wxString::FromUTF8("°C"));
m_temperature_input->SetHint("45-85" + wxString::FromUTF8(u8"\u2103" /* °C */));
}
m_time_input->SetHint("1-24 h");
@@ -1467,7 +1467,7 @@ int AMSDryCtrWin::update_dryness_status(DevAms* dev_ams)
if (m_ams_info.m_temperature != dev_ams->GetCurrentTemperature()) {
updated += 1;
m_ams_info.m_temperature = dev_ams->GetCurrentTemperature();
m_temperature_data_label->SetLabel(std::to_string(m_ams_info.m_temperature) + wxString::FromUTF8("°C"));
m_temperature_data_label->SetLabel(std::to_string(m_ams_info.m_temperature) + wxString::FromUTF8(u8"\u2103" /* °C */));
}
if (is_dry_ctr_idle(dev_ams)) {
+1 -1
View File
@@ -36,7 +36,7 @@ namespace Slic3r
AppConfig* config = GUI::wxGetApp().app_config;
if (!config)
return;
const auto& local_machines = config->get_local_machines();
const auto local_machines = config->get_local_machines();
for (auto& it : local_machines) {
const auto& m = it.second;
if (localMachineList.count(m.dev_id))
+100 -18
View File
@@ -111,14 +111,25 @@ wxString get_formatted_tooltip_text(const ConfigOptionDef& opt, const t_config_o
{
wxString tooltip = _(opt.tooltip);
std::string opt_id = id;
auto hash_pos = opt_id.find("#");
std::string parameter_name = id;
std::string opt_key = id;
int opt_idx = 0;
const size_t hash_pos = static_cast<std::string>(id).find("#");
if (hash_pos != std::string::npos) {
opt_id.replace(hash_pos, 1,"[");
opt_id += "]";
parameter_name.replace(hash_pos, 1, "[");
parameter_name += "]";
std::string temp_str = id;
boost::erase_head(temp_str, hash_pos + 1);
size_t orig_opt_idx = atoi(temp_str.c_str());
opt_idx = orig_opt_idx >= 0 ? orig_opt_idx : 0;
boost::erase_tail(opt_key, opt_key.size() - hash_pos);
}
tooltip += (tooltip.empty() ? "" : "\n\n") + _(L("parameter name")) + ": " + opt_id;
tooltip += (tooltip.empty() ? "" : "\n\n") + _(L("parameter name")) + ": " + parameter_name;
// Orca:
// We can't use Orca's default values as-is because they sometimes depend on other values.
@@ -126,7 +137,7 @@ wxString get_formatted_tooltip_text(const ConfigOptionDef& opt, const t_config_o
if (const Preset* print_parent_preset = wxGetApp().preset_bundle->prints.get_selected_preset_parent()) {
const DynamicPrintConfig& parent_config = print_parent_preset->config;
if (!parent_config.has(opt_id))
if (!parent_config.has(opt_key))
return tooltip;
wxString side_text = from_u8(opt.sidetext);
@@ -135,18 +146,71 @@ wxString get_formatted_tooltip_text(const ConfigOptionDef& opt, const t_config_o
if (opt.sidetext == L("layers"))
side_text = " " + _(side_text);
if (opt.type == coFloat || opt.type == coInt || opt.type == coPercent || opt.type == coFloatOrPercent) {
double default_value = 0.;
if (opt.type == coFloat || opt.type == coInt || opt.type == coPercent || opt.type == coFloatOrPercent ||
opt.type == coFloats || opt.type == coInts || opt.type == coPercents || opt.type == coFloatsOrPercents) {
double default_value = std::numeric_limits<double>::quiet_NaN();
if (opt.type == coFloat)
default_value = parent_config.option<ConfigOptionFloat>(opt_id)->value;
default_value = parent_config.option<ConfigOptionFloat>(opt_key)->value;
else if (opt.type == coFloats) {
if (opt.nullable) {
auto opt_floats_nullable = parent_config.option<ConfigOptionFloatsNullable>(opt_key);
if (!opt_floats_nullable->values.empty())
default_value = opt_floats_nullable->get_at(opt_idx);
} else {
auto opt_floats = parent_config.option<ConfigOptionFloats>(opt_key);
if (!opt_floats->values.empty())
default_value = opt_floats->get_at(opt_idx);
}
}
else if (opt.type == coInt)
default_value = parent_config.option<ConfigOptionInt>(opt_id)->value;
default_value = parent_config.option<ConfigOptionInt>(opt_key)->value;
else if(opt.type == coInts) {
if (opt.nullable) {
auto opt_ints_nullable = parent_config.option<ConfigOptionIntsNullable>(opt_key);
if (!opt_ints_nullable->values.empty())
default_value = opt_ints_nullable->get_at(opt_idx);
} else {
auto opt_ints = parent_config.option<ConfigOptionInts>(opt_key);
if (!opt_ints->values.empty())
default_value = opt_ints->get_at(opt_idx);
}
}
else if (opt.type == coPercent)
default_value = parent_config.option<ConfigOptionPercent>(opt_id)->value;
else if (opt.type == coFloatOrPercent) {
default_value = parent_config.option<ConfigOptionFloatOrPercent>(opt_id)->value;
if (parent_config.option<ConfigOptionFloatOrPercent>(opt_id)->percent)
default_value = parent_config.option<ConfigOptionPercent>(opt_key)->value;
else if (opt.type == coPercents) {
if (opt.nullable) {
auto opt_percents_nullable = parent_config.option<ConfigOptionPercentsNullable>(opt_key);
if (!opt_percents_nullable->values.empty())
default_value = opt_percents_nullable->get_at(opt_idx);
} else {
auto opt_percents = parent_config.option<ConfigOptionPercents>(opt_key);
if (!opt_percents->values.empty())
default_value = opt_percents->get_at(opt_idx);
}
}
else if (opt.type == coFloatOrPercent || opt.type == coFloatsOrPercents) {
bool is_percent = false;
if (opt.type == coFloatOrPercent) {
default_value = parent_config.option<ConfigOptionFloatOrPercent>(opt_key)->value;
is_percent = parent_config.option<ConfigOptionFloatOrPercent>(opt_key)->percent;
} else if (opt.type == coFloatsOrPercents) {
if (opt.nullable) {
auto opt_floats_or_percents_nullable = parent_config.option<ConfigOptionFloatsOrPercentsNullable>(opt_key);
if (!opt_floats_or_percents_nullable->values.empty()) {
default_value = opt_floats_or_percents_nullable->get_at(opt_idx).value;
is_percent = opt_floats_or_percents_nullable->get_at(opt_idx).percent;
}
} else {
auto opt_floats_or_percents = parent_config.option<ConfigOptionFloatsOrPercents>(opt_key);
if (!opt_floats_or_percents->values.empty()) {
default_value = opt_floats_or_percents->get_at(opt_idx).value;
is_percent = opt_floats_or_percents->get_at(opt_idx).percent;
}
}
}
if (is_percent)
side_text = "%";
else if (!side_text.empty()) {
static std::string postfix = " or %";
@@ -156,20 +220,38 @@ wxString get_formatted_tooltip_text(const ConfigOptionDef& opt, const t_config_o
}
}
tooltip += "\n\n" + _(L("Default")) + ": " + _(double_to_string(default_value)) + _(side_text);
if (!std::isnan(default_value))
tooltip += "\n\n" + _(L("Default")) + ": " + _(double_to_string(default_value)) + _(side_text);
if (opt.min > -FLT_MAX && opt.max < FLT_MAX) {
tooltip += "\n" + _(L("Range")) + ": [" +
_(double_to_string(opt.min)) + _(side_text) + ", " +
_(double_to_string(opt.max)) + _(side_text) + "]";
}
} else if (opt.type == coBool || opt.type == coString) {
} else if (opt.type == coBool || opt.type == coBools || opt.type == coString || opt.type == coStrings) {
std::string default_value = "";
if (opt.type == coString)
default_value = parent_config.option<ConfigOptionString>(opt_id)->value;
default_value = parent_config.option<ConfigOptionString>(opt_key)->value;
else if (opt.type == coStrings) {
auto opt_strings = parent_config.option<ConfigOptionStrings>(opt_key);
if (!opt_strings->values.empty())
default_value = opt_strings->get_at(opt_idx);
}
else if (opt.type == coBool)
default_value = parent_config.option<ConfigOptionBool>(opt_id)->value ? "true" : "false";
default_value = parent_config.option<ConfigOptionBool>(opt_key)->value != 0 ? "true" : "false";
else if (opt.type == coBools) {
if (opt.nullable) {
auto opt_bools_nullable = parent_config.option<ConfigOptionBoolsNullable>(opt_key);
if (!opt_bools_nullable->values.empty())
default_value = opt_bools_nullable->get_at(opt_idx) != 0 ? "true" : "false";
} else {
auto opt_bools = parent_config.option<ConfigOptionBools>(opt_key);
if (!opt_bools->values.empty())
default_value = opt_bools->get_at(opt_idx) != 0 ? "true" : "false";
}
}
tooltip += "\n\n" + _(L("Default")) + ": " +
(default_value.empty() ? _(L("Empty string")) : _(default_value) + _(side_text));
+3
View File
@@ -1134,6 +1134,9 @@ void GCodeViewer::load_as_gcode(const GCodeProcessorResult& gcode_result, const
if (current_top_layer_only != required_top_layer_only)
m_viewer.toggle_top_layer_only_view_range();
// ORCA: darken layers below the current one while scrubbing the preview (ported from preFlight)
m_viewer.set_dim_previous_layers(get_app_config()->get_bool("preview_dim_previous_layers"));
// avoid processing if called with the same gcode_result
if (m_last_result_id == gcode_result.id && wxGetApp().is_editor()) {
//BBS: add logs
+4
View File
@@ -333,6 +333,10 @@ public:
libvgcode::EViewType get_view_type() const { return m_viewer.get_view_type(); }
// ORCA: darken layers below the current top layer while scrubbing the preview (ported from preFlight)
void set_dim_previous_layers(bool value) { m_viewer.set_dim_previous_layers(value); }
bool is_dim_previous_layers() const { return m_viewer.is_dim_previous_layers(); }
void set_layers_z_range(const std::array<unsigned int, 2>& layers_z_range);
bool is_legend_shown() const { return m_legend_visible && m_legend_enabled; }
+114 -153
View File
@@ -4,6 +4,7 @@
#include "MainFrame.hpp"
#include "MsgDialog.hpp"
#include "Widgets/Label.hpp"
#include "Widgets/DialogButtons.hpp"
#include "BitmapCache.hpp"
#include "wxExtensions.hpp"
#include "slic3r/Utils/bambu_networking.hpp"
@@ -12,6 +13,10 @@
#include <wx/stattext.h>
#include <wx/collpane.h>
#define BORDER_W FromDIP(20)
#define TEXT_WRAP FromDIP(400)
#define DIALOG_WIDTH FromDIP(440)
namespace Slic3r {
namespace GUI {
@@ -30,10 +35,10 @@ NetworkPluginDownloadDialog::NetworkPluginDownloadDialog(wxWindow* parent, Mode
wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1));
auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(DIALOG_WIDTH, 1));
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
main_sizer->Add(m_line_top, 0, wxEXPAND, 0);
main_sizer->Add(0, 0, 0, wxTOP, FromDIP(20));
main_sizer->AddSpacer(BORDER_W);
SetSizer(main_sizer);
@@ -52,157 +57,136 @@ void NetworkPluginDownloadDialog::create_missing_plugin_ui()
{
wxBoxSizer* main_sizer = static_cast<wxBoxSizer*>(GetSizer());
auto* desc = new wxStaticText(this, wxID_ANY,
auto* desc = new Label(this,
m_mode == Mode::CorruptedPlugin ?
_L("The Bambu Network Plug-in is corrupted or incompatible. Please reinstall it.") :
_L("The Bambu Network Plug-in is required for cloud features, printer discovery, and remote printing."));
desc->SetFont(::Label::Body_13);
desc->Wrap(FromDIP(400));
main_sizer->Add(desc, 0, wxLEFT | wxRIGHT, FromDIP(25));
main_sizer->Add(0, 0, 0, wxTOP, FromDIP(15));
desc->Wrap(TEXT_WRAP);
desc->SetMaxSize(wxSize(TEXT_WRAP, -1));
main_sizer->Add(desc, 0, wxLEFT | wxRIGHT, BORDER_W);
main_sizer->AddSpacer(FromDIP(15));
if (!m_error_message.empty()) {
auto* error_label = new wxStaticText(this, wxID_ANY,
wxString::Format(_L("Error: %s"), wxString::FromUTF8(m_error_message)));
error_label->SetFont(::Label::Body_13);
error_label->SetForegroundColour(wxColour(208, 93, 93));
error_label->Wrap(FromDIP(400));
main_sizer->Add(error_label, 0, wxLEFT | wxRIGHT, FromDIP(25));
main_sizer->Add(0, 0, 0, wxTOP, FromDIP(10));
error_label->Wrap(TEXT_WRAP);
error_label->SetMaxSize(wxSize(TEXT_WRAP, -1));
main_sizer->Add(error_label, 0, wxLEFT | wxRIGHT, BORDER_W);
main_sizer->AddSpacer(FromDIP(5));
if (!m_error_details.empty()) {
m_details_pane = new wxCollapsiblePane(this, wxID_ANY, _L("Show details"));
auto* pane = m_details_pane->GetPane();
auto* pane_sizer = new wxBoxSizer(wxVERTICAL);
auto expand_btn = new Button(this, _L("Show details"));
expand_btn->SetStyle(ButtonStyle::Regular, ButtonType::Compact);
main_sizer->Add(expand_btn, 0, wxLEFT, BORDER_W);
main_sizer->AddSpacer(FromDIP(5));
auto details_text = new wxTextCtrl(this, wxID_ANY, wxString::FromUTF8(m_error_details),
wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxNO_BORDER);
auto* details_text = new wxStaticText(pane, wxID_ANY, wxString::FromUTF8(m_error_details));
details_text->SetFont(wxGetApp().code_font());
details_text->Wrap(FromDIP(380));
pane_sizer->Add(details_text, 0, wxALL, FromDIP(10));
details_text->SetBackgroundColour(wxColour("#F1F1F1"));
details_text->SetMaxSize(wxSize(TEXT_WRAP, -1));
main_sizer->Add(details_text, 0, wxLEFT | wxRIGHT | wxEXPAND, BORDER_W);
pane->SetSizer(pane_sizer);
main_sizer->Add(m_details_pane, 0, wxLEFT | wxRIGHT | wxEXPAND, FromDIP(25));
main_sizer->Add(0, 0, 0, wxTOP, FromDIP(10));
details_text->Hide();
expand_btn->Bind(wxEVT_BUTTON, [this, details_text, expand_btn](wxCommandEvent&){
Freeze();
details_text->Show(!details_text->IsShown());
expand_btn->SetLabel(details_text->IsShown() ? _L("Hide details") : _L("Show details"));
Layout();
Fit();
Refresh();
Thaw();
});
main_sizer->AddSpacer(FromDIP(15));
}
}
auto* version_label = new wxStaticText(this, wxID_ANY, _L("Version to install:"));
version_label->SetFont(::Label::Body_13);
main_sizer->Add(version_label, 0, wxLEFT | wxRIGHT, FromDIP(25));
main_sizer->Add(0, 0, 0, wxTOP, FromDIP(5));
auto* version_label = new Label(this, _L("Version to install:"));
main_sizer->Add(version_label, 0, wxLEFT | wxRIGHT, BORDER_W);
main_sizer->AddSpacer(FromDIP(3));
setup_version_selector();
main_sizer->Add(m_version_combo, 0, wxLEFT | wxRIGHT | wxEXPAND, FromDIP(25));
main_sizer->Add(0, 0, 0, wxTOP, FromDIP(20));
auto* btn_sizer = new wxBoxSizer(wxHORIZONTAL);
btn_sizer->Add(0, 0, 1, wxEXPAND, 0);
main_sizer->Add(m_version_combo, 0, wxLEFT | wxRIGHT | wxEXPAND, BORDER_W);
main_sizer->AddSpacer(15);
StateColor btn_bg_green(
std::pair<wxColour, int>(wxColour(0, 137, 123), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(38, 166, 154), StateColor::Hovered),
std::pair<wxColour, int>(wxColour(0, 150, 136), StateColor::Normal));
auto dlg_btns = new DialogButtons(this,
{"Download and Install", "Skip for Now"},
_L("Download and Install") // Primary button
);
StateColor btn_bg_white(
std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Hovered),
std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
dlg_btns->GetButtonFromIndex(0)->Bind(wxEVT_BUTTON, &NetworkPluginDownloadDialog::on_download, this);
dlg_btns->GetButtonFromIndex(1)->Bind(wxEVT_BUTTON, &NetworkPluginDownloadDialog::on_skip, this);
auto* btn_download = new Button(this, _L("Download and Install"));
btn_download->SetBackgroundColor(btn_bg_green);
btn_download->SetBorderColor(*wxWHITE);
btn_download->SetTextColor(*wxWHITE);
btn_download->SetFont(::Label::Body_12);
btn_download->SetMinSize(wxSize(FromDIP(120), FromDIP(24)));
btn_download->Bind(wxEVT_BUTTON, &NetworkPluginDownloadDialog::on_download, this);
btn_sizer->Add(btn_download, 0, wxRIGHT, FromDIP(10));
auto* btn_skip = new Button(this, _L("Skip for Now"));
btn_skip->SetBackgroundColor(btn_bg_white);
btn_skip->SetBorderColor(wxColour(38, 46, 48));
btn_skip->SetFont(::Label::Body_12);
btn_skip->SetMinSize(wxSize(FromDIP(100), FromDIP(24)));
btn_skip->Bind(wxEVT_BUTTON, &NetworkPluginDownloadDialog::on_skip, this);
btn_sizer->Add(btn_skip, 0, wxRIGHT, FromDIP(10));
main_sizer->Add(btn_sizer, 0, wxLEFT | wxRIGHT | wxEXPAND, FromDIP(20));
main_sizer->Add(0, 0, 0, wxBOTTOM, FromDIP(20));
main_sizer->Add(dlg_btns, 0, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, FromDIP(10));
}
void NetworkPluginDownloadDialog::create_update_available_ui(const std::string& current_version)
{
wxBoxSizer* main_sizer = static_cast<wxBoxSizer*>(GetSizer());
auto* desc = new wxStaticText(this, wxID_ANY,
auto* desc = new Label(this,
_L("A new version of the Bambu Network Plug-in is available."));
desc->SetFont(::Label::Body_13);
desc->Wrap(FromDIP(400));
main_sizer->Add(desc, 0, wxLEFT | wxRIGHT, FromDIP(25));
main_sizer->Add(0, 0, 0, wxTOP, FromDIP(15));
desc->Wrap(TEXT_WRAP);
desc->SetMaxSize(wxSize(TEXT_WRAP, -1));
main_sizer->Add(desc, 0, wxLEFT | wxRIGHT, BORDER_W);
main_sizer->AddSpacer(FromDIP(15));
auto* version_text = new wxStaticText(this, wxID_ANY,
auto* version_text = new Label(this,
wxString::Format(_L("Current version: %s"), wxString::FromUTF8(current_version)));
version_text->SetFont(::Label::Body_13);
main_sizer->Add(version_text, 0, wxLEFT | wxRIGHT, FromDIP(25));
main_sizer->Add(0, 0, 0, wxTOP, FromDIP(10));
main_sizer->Add(version_text, 0, wxLEFT | wxRIGHT, BORDER_W);
main_sizer->AddSpacer(FromDIP(15));
auto* update_label = new wxStaticText(this, wxID_ANY, _L("Update to version:"));
update_label->SetFont(::Label::Body_13);
main_sizer->Add(update_label, 0, wxLEFT | wxRIGHT, FromDIP(25));
main_sizer->Add(0, 0, 0, wxTOP, FromDIP(5));
auto* update_label = new Label(this, _L("Update to version:"));
main_sizer->Add(update_label, 0, wxLEFT | wxRIGHT, BORDER_W);
main_sizer->AddSpacer(FromDIP(3));
setup_version_selector();
main_sizer->Add(m_version_combo, 0, wxLEFT | wxRIGHT | wxEXPAND, FromDIP(25));
main_sizer->Add(0, 0, 0, wxTOP, FromDIP(20));
main_sizer->Add(m_version_combo, 0, wxLEFT | wxRIGHT | wxEXPAND, BORDER_W);
main_sizer->AddSpacer(20);
auto* btn_sizer = new wxBoxSizer(wxHORIZONTAL);
btn_sizer->Add(0, 0, 1, wxEXPAND, 0);
auto daa_sizer = new wxBoxSizer(wxHORIZONTAL);
auto cfg = wxGetApp().app_config;
StateColor btn_bg_green(
std::pair<wxColour, int>(wxColour(0, 137, 123), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(38, 166, 154), StateColor::Hovered),
std::pair<wxColour, int>(wxColour(0, 150, 136), StateColor::Normal));
auto daa_chk = new CheckBox(this);
daa_chk->SetValue(cfg->is_network_update_prompt_disabled());
daa_chk->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent& e){
auto cfg = wxGetApp().app_config;
cfg->set_network_update_prompt_disabled(e.IsChecked());
cfg->save();
});
StateColor btn_bg_white(
std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Hovered),
std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
auto daa_str = new Label(this, _L("Don't Ask Again"));
auto on_toggle = [this, daa_chk]() {
daa_chk->SetValue(!daa_chk->GetValue());
wxCommandEvent evt(wxEVT_TOGGLEBUTTON, daa_chk->GetId());
evt.SetEventObject(daa_chk);
daa_chk->GetEventHandler()->ProcessEvent(evt);
};
daa_str->Bind(wxEVT_LEFT_DOWN, [on_toggle](wxMouseEvent& e) {if(!e.LeftDClick()) on_toggle();});
daa_str->Bind(wxEVT_LEFT_DCLICK, [on_toggle](wxMouseEvent& e) {on_toggle();});
auto* btn_download = new Button(this, _L("Update Now"));
btn_download->SetBackgroundColor(btn_bg_green);
btn_download->SetBorderColor(*wxWHITE);
btn_download->SetTextColor(*wxWHITE);
btn_download->SetFont(::Label::Body_12);
btn_download->SetMinSize(wxSize(FromDIP(100), FromDIP(24)));
btn_download->Bind(wxEVT_BUTTON, &NetworkPluginDownloadDialog::on_download, this);
btn_sizer->Add(btn_download, 0, wxRIGHT, FromDIP(10));
daa_sizer->Add(daa_chk, 0, wxALIGN_CENTER_VERTICAL);
daa_sizer->Add(daa_str, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(5));
auto* btn_remind = new Button(this, _L("Remind Later"));
btn_remind->SetBackgroundColor(btn_bg_white);
btn_remind->SetBorderColor(wxColour(38, 46, 48));
btn_remind->SetFont(::Label::Body_12);
btn_remind->SetMinSize(wxSize(FromDIP(100), FromDIP(24)));
btn_remind->Bind(wxEVT_BUTTON, &NetworkPluginDownloadDialog::on_remind_later, this);
btn_sizer->Add(btn_remind, 0, wxRIGHT, FromDIP(10));
main_sizer->Add(daa_sizer, 0, wxLEFT | wxRIGHT | wxEXPAND, BORDER_W);
main_sizer->AddSpacer(10);
auto* btn_skip = new Button(this, _L("Skip Version"));
btn_skip->SetBackgroundColor(btn_bg_white);
btn_skip->SetBorderColor(wxColour(38, 46, 48));
btn_skip->SetFont(::Label::Body_12);
btn_skip->SetMinSize(wxSize(FromDIP(100), FromDIP(24)));
btn_skip->Bind(wxEVT_BUTTON, &NetworkPluginDownloadDialog::on_skip_version, this);
btn_sizer->Add(btn_skip, 0, wxRIGHT, FromDIP(10));
auto dlg_btns = new DialogButtons(this,
{"Update Now", "Remind Later", "Skip Version"},
_L("Update Now")
);
auto* btn_dont_ask = new Button(this, _L("Don't Ask Again"));
btn_dont_ask->SetBackgroundColor(btn_bg_white);
btn_dont_ask->SetBorderColor(wxColour(38, 46, 48));
btn_dont_ask->SetFont(::Label::Body_12);
btn_dont_ask->SetMinSize(wxSize(FromDIP(110), FromDIP(24)));
btn_dont_ask->Bind(wxEVT_BUTTON, &NetworkPluginDownloadDialog::on_dont_ask, this);
btn_sizer->Add(btn_dont_ask, 0, wxRIGHT, FromDIP(10));
dlg_btns->GetButtonFromIndex(0)->Bind(wxEVT_BUTTON, &NetworkPluginDownloadDialog::on_download, this);
dlg_btns->GetButtonFromIndex(1)->Bind(wxEVT_BUTTON, &NetworkPluginDownloadDialog::on_remind_later, this);
dlg_btns->GetButtonFromIndex(2)->Bind(wxEVT_BUTTON, &NetworkPluginDownloadDialog::on_skip_version, this);
main_sizer->Add(btn_sizer, 0, wxLEFT | wxRIGHT | wxEXPAND, FromDIP(20));
main_sizer->Add(0, 0, 0, wxBOTTOM, FromDIP(20));
main_sizer->Add(dlg_btns, 0, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, FromDIP(10));
}
wxString network_version_label(const NetworkLibraryVersionInfo& ver)
@@ -222,7 +206,6 @@ void NetworkPluginDownloadDialog::setup_version_selector()
{
m_version_combo = new ComboBox(this, wxID_ANY, wxEmptyString,
wxDefaultPosition, wxSize(FromDIP(380), FromDIP(28)), 0, nullptr, wxCB_READONLY);
m_version_combo->SetFont(::Label::Body_13);
m_available_versions = get_all_available_versions();
for (const auto& ver : m_available_versions)
@@ -294,10 +277,10 @@ NetworkPluginRestartDialog::NetworkPluginRestartDialog(wxWindow* parent)
wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1));
auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(DIALOG_WIDTH, 1));
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
main_sizer->Add(m_line_top, 0, wxEXPAND, 0);
main_sizer->Add(0, 0, 0, wxTOP, FromDIP(20));
main_sizer->AddSpacer(BORDER_W);
auto* icon_sizer = new wxBoxSizer(wxHORIZONTAL);
auto* icon_bitmap = new wxStaticBitmap(this, wxID_ANY,
@@ -306,61 +289,39 @@ NetworkPluginRestartDialog::NetworkPluginRestartDialog(wxWindow* parent)
auto* text_sizer = new wxBoxSizer(wxVERTICAL);
auto* desc = new wxStaticText(this, wxID_ANY,
auto* desc = new Label(this,
_L("The Bambu Network Plug-in has been installed successfully."));
desc->SetFont(::Label::Body_14);
desc->Wrap(FromDIP(350));
desc->Wrap(TEXT_WRAP);
desc->SetMaxSize(wxSize(TEXT_WRAP, -1));
text_sizer->Add(desc, 0, wxTOP, FromDIP(10));
text_sizer->Add(0, 0, 0, wxTOP, FromDIP(10));
text_sizer->AddSpacer(FromDIP(10));
auto* restart_msg = new wxStaticText(this, wxID_ANY,
auto* restart_msg = new Label(this,
_L("A restart is required to load the new plug-in. Would you like to restart now?"));
restart_msg->SetFont(::Label::Body_13);
restart_msg->Wrap(FromDIP(350));
restart_msg->Wrap(TEXT_WRAP);
restart_msg->SetMaxSize(wxSize(TEXT_WRAP, -1));
text_sizer->Add(restart_msg, 0, wxBOTTOM, FromDIP(10));
icon_sizer->Add(text_sizer, 1, wxEXPAND | wxRIGHT, FromDIP(20));
main_sizer->Add(icon_sizer, 0, wxLEFT | wxRIGHT | wxEXPAND, FromDIP(15));
main_sizer->Add(0, 0, 0, wxTOP, FromDIP(20));
icon_sizer->Add(text_sizer, 1, wxEXPAND | wxRIGHT, BORDER_W);
main_sizer->Add(icon_sizer, 0, wxLEFT | wxRIGHT | wxEXPAND, BORDER_W);
main_sizer->AddSpacer(15);
auto* btn_sizer = new wxBoxSizer(wxHORIZONTAL);
btn_sizer->Add(0, 0, 1, wxEXPAND, 0);
auto dlg_btns = new DialogButtons(this,
{"Restart Now", "Restart Later"},
_L("Restart Now") // Primary button
);
StateColor btn_bg_green(
std::pair<wxColour, int>(wxColour(0, 137, 123), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(38, 166, 154), StateColor::Hovered),
std::pair<wxColour, int>(wxColour(0, 150, 136), StateColor::Normal));
StateColor btn_bg_white(
std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Hovered),
std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
auto* btn_restart = new Button(this, _L("Restart Now"));
btn_restart->SetBackgroundColor(btn_bg_green);
btn_restart->SetBorderColor(*wxWHITE);
btn_restart->SetTextColor(*wxWHITE);
btn_restart->SetFont(::Label::Body_12);
btn_restart->SetMinSize(wxSize(FromDIP(100), FromDIP(24)));
btn_restart->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {
dlg_btns->GetButtonFromIndex(0)->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {
m_restart_now = true;
EndModal(wxID_OK);
});
btn_sizer->Add(btn_restart, 0, wxRIGHT, FromDIP(10));
auto* btn_later = new Button(this, _L("Restart Later"));
btn_later->SetBackgroundColor(btn_bg_white);
btn_later->SetBorderColor(wxColour(38, 46, 48));
btn_later->SetFont(::Label::Body_12);
btn_later->SetMinSize(wxSize(FromDIP(100), FromDIP(24)));
btn_later->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {
dlg_btns->GetButtonFromIndex(1)->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {
m_restart_now = false;
EndModal(wxID_CANCEL);
});
btn_sizer->Add(btn_later, 0, wxRIGHT, FromDIP(10));
main_sizer->Add(btn_sizer, 0, wxLEFT | wxRIGHT | wxEXPAND, FromDIP(20));
main_sizer->Add(0, 0, 0, wxBOTTOM, FromDIP(20));
main_sizer->Add(dlg_btns, 0, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, FromDIP(10));
SetSizer(main_sizer);
Layout();
-1
View File
@@ -56,7 +56,6 @@ private:
Mode m_mode;
ComboBox* m_version_combo{nullptr};
wxCollapsiblePane* m_details_pane{nullptr};
std::string m_error_message;
std::string m_error_details;
std::vector<NetworkLibraryVersionInfo> m_available_versions;
+23 -13
View File
@@ -1844,9 +1844,9 @@ bool Sidebar::priv::is_fila_switch_ready()
void Sidebar::priv::show_fila_switch_msg(bool ready)
{
wxString msg = ready ? _L("Filament switcher detected. All AMS filaments are now available for both extruders. "
"The slicer will auto-assign for optimal printing. ") :
"The slicer will auto-assign for optimal printing.") :
_L("A filament switcher is detected but not calibrated and thus currently unavailable. "
"Please calibrate it on the printer and synchronize before use. ");
"Please calibrate it on the printer and synchronize before use.");
long style = ready ? (wxICON_INFORMATION | wxOK) : (wxICON_WARNING | wxOK);
// Orca: drop the vendor "Learn more" tracking link; there is no Orca help page for the switch yet.
@@ -13513,7 +13513,7 @@ bool Plater::up_to_date(bool saved, bool backup)
!Slic3r::has_other_changes(backup));
}
void Plater::add_model(bool imperial_units, std::string fname)
bool Plater::add_model(bool imperial_units, std::string fname)
{
wxArrayString input_files;
@@ -13521,7 +13521,7 @@ void Plater::add_model(bool imperial_units, std::string fname)
if (fname.empty()) {
wxGetApp().import_model(this, input_files);
if (input_files.empty())
return;
return false;
for (const auto& file : input_files)
paths.emplace_back(into_path(file));
@@ -13565,7 +13565,8 @@ void Plater::add_model(bool imperial_units, std::string fname)
auto strategy = LoadStrategy::LoadModel;
if (imperial_units) strategy = strategy | LoadStrategy::ImperialUnits;
if (!load_files(paths, strategy, ask_multi).empty()) {
const bool loaded = !load_files(paths, strategy, ask_multi).empty();
if (loaded) {
if (get_project_name() == _L("Untitled") && paths.size() > 0) {
boost::filesystem::path full_path(paths[0].string());
@@ -13574,6 +13575,7 @@ void Plater::add_model(bool imperial_units, std::string fname)
wxGetApp().mainframe->update_title();
}
return loaded;
}
void Plater::calib_pa(const Calib_Params& params)
@@ -13860,7 +13862,8 @@ void Plater::cut_horizontal(size_t obj_idx, size_t instance_idx, double z, Model
}
void Plater::_calib_pa_tower(const Calib_Params& params) {
add_model(false, Slic3r::resources_dir() + "/calib/pressure_advance/tower_with_seam.drc");
if (!add_model(false, Slic3r::resources_dir() + "/calib/pressure_advance/tower_with_seam.drc"))
return;
auto& print_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
@@ -14100,7 +14103,8 @@ void Plater::calib_temp(const Calib_Params& params) {
wxGetApp().mainframe->select_tab(size_t(MainFrame::tp3DEditor));
if (params.mode != CalibMode::Calib_Temp_Tower) return;
add_model(false, Slic3r::resources_dir() + "/calib/temperature_tower/temperature_tower.drc");
if (!add_model(false, Slic3r::resources_dir() + "/calib/temperature_tower/temperature_tower.drc"))
return;
auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
auto start_temp = lround(params.start);
@@ -14176,7 +14180,8 @@ void Plater::calib_max_vol_speed(const Calib_Params& params)
wxGetApp().mainframe->select_tab(size_t(MainFrame::tp3DEditor));
if (params.mode != CalibMode::Calib_Vol_speed_Tower)
return;
add_model(false, Slic3r::resources_dir() + "/calib/volumetric_speed/SpeedTestStructure.drc");
if (!add_model(false, Slic3r::resources_dir() + "/calib/volumetric_speed/SpeedTestStructure.drc"))
return;
auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
@@ -14255,7 +14260,8 @@ void Plater::calib_retraction(const Calib_Params& params)
if (params.mode != CalibMode::Calib_Retraction_tower)
return;
add_model(false, Slic3r::resources_dir() + "/calib/retraction/retraction_tower.drc");
if (!add_model(false, Slic3r::resources_dir() + "/calib/retraction/retraction_tower.drc"))
return;
auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
@@ -14314,7 +14320,8 @@ void Plater::calib_VFA(const Calib_Params& params)
if (params.mode != CalibMode::Calib_VFA_Tower)
return;
add_model(false, Slic3r::resources_dir() + "/calib/vfa/vfa.drc");
if (!add_model(false, Slic3r::resources_dir() + "/calib/vfa/vfa.drc"))
return;
auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
@@ -14359,7 +14366,8 @@ void Plater::calib_input_shaping_freq(const Calib_Params& params)
if (params.mode != CalibMode::Calib_Input_shaping_freq)
return;
add_model(false, Slic3r::resources_dir() + (params.test_model < 1 ? "/calib/input_shaping/ringing_tower.drc" : "/calib/input_shaping/fast_tower_test.drc"));
if (!add_model(false, Slic3r::resources_dir() + (params.test_model < 1 ? "/calib/input_shaping/ringing_tower.drc" : "/calib/input_shaping/fast_tower_test.drc")))
return;
auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
@@ -14424,7 +14432,8 @@ void Plater::calib_input_shaping_damp(const Calib_Params& params)
if (params.mode != CalibMode::Calib_Input_shaping_damp)
return;
add_model(false, Slic3r::resources_dir() + (params.test_model < 1 ? "/calib/input_shaping/ringing_tower.drc" : "/calib/input_shaping/fast_tower_test.drc"));
if (!add_model(false, Slic3r::resources_dir() + (params.test_model < 1 ? "/calib/input_shaping/ringing_tower.drc" : "/calib/input_shaping/fast_tower_test.drc")))
return;
auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
@@ -14491,7 +14500,8 @@ void Plater::Calib_Cornering(const Calib_Params& params)
const std::string cornering_model_path = params.test_model == 0
? "/calib/input_shaping/ringing_tower.drc"
: (params.test_model == 1 ? "/calib/input_shaping/fast_tower_test.drc" : "/calib/cornering/SCV-V2.drc");
add_model(false, Slic3r::resources_dir() + cornering_model_path);
if (!add_model(false, Slic3r::resources_dir() + cornering_model_path))
return;
auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
+2 -1
View File
@@ -328,7 +328,8 @@ public:
bool open_3mf_file(const fs::path &file_path);
int get_3mf_file_count(std::vector<fs::path> paths);
void add_file();
void add_model(bool imperial_units = false, std::string fname = "");
// Returns false when no object was added (e.g. the user cancelled the load dialog).
bool add_model(bool imperial_units = false, std::string fname = "");
void import_zip_archive();
void import_sl1_archive();
void extract_config_from_project();
+22 -1
View File
@@ -3,6 +3,7 @@
#include "GUI_App.hpp"
#include "MainFrame.hpp"
#include "Plater.hpp"
#include "GLCanvas3D.hpp" // ORCA: for live preview refresh when toggling "Dim lower layers"
#include "MsgDialog.hpp"
#include "I18N.hpp"
#include "libslic3r/AppConfig.hpp"
@@ -1049,6 +1050,16 @@ wxBoxSizer *PreferencesDialog::create_item_checkbox(wxString title, wxString too
wxGetApp().mainframe->m_webview->SendCloudProvidersInfo();
}
}
// ORCA: apply the preview dimming change immediately to the currently loaded preview (ported from preFlight)
else if (param == "preview_dim_previous_layers") {
if (Plater* plater = wxGetApp().plater()) {
if (GLCanvas3D* canvas = plater->get_preview_canvas3D()) {
canvas->get_gcode_viewer().set_dim_previous_layers(app_config->get_bool(param));
canvas->set_as_dirty();
canvas->request_extra_frame();
}
}
}
#ifdef __WXMSW__
if (param == "associate_3mf") {
@@ -1893,11 +1904,21 @@ void PreferencesDialog::create_items()
);
g_sizer->Add(item_fps_overlay);
//// GRAPHICS > G-code Preview
g_sizer->Add(create_item_title(_L("G-code Preview")), 1, wxEXPAND);
auto item_dim_previous_layers = create_item_checkbox(
_L("Dim lower layers"),
_L("When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."),
"preview_dim_previous_layers"
);
g_sizer->Add(item_dim_previous_layers);
g_sizer->AddSpacer(FromDIP(10));
sizer_page->Add(g_sizer, 0, wxEXPAND);
//////////////////////////
//// ONLINE TAB
//// ONLINE TAB
/////////////////////////////////////
m_pref_tabs->AppendItem(_L("Online"));
f_sizers.push_back(new wxFlexGridSizer(1, 1, v_gap, 0));
+2 -2
View File
@@ -4539,7 +4539,7 @@ bool SelectMachineDialog::CheckErrorExtruderNozzleWithSlicing(MachineObject* obj
pos, installed_nozzle_str, slicing_nozzle_str);
std::vector<wxString> params{ error_message };
params.emplace_back(_L("Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting."));
params.emplace_back(_L("Tips: If you changed your nozzle of your printer lately, please go to 'Device -> Printer parts' to change your nozzle setting."));
show_status(PrintDialogStatus::PrintStatusNozzleMatchInvalid, params);
return false;
}
@@ -4564,7 +4564,7 @@ bool SelectMachineDialog::CheckErrorExtruderNozzleWithSlicing(MachineObject* obj
msg_params.emplace_back(nozzle_message);
}
msg_params.emplace_back(_L("Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting."));
msg_params.emplace_back(_L("Tips: If you changed your nozzle of your printer lately, please go to 'Device -> Printer parts' to change your nozzle setting."));
show_status(PrintDialogStatus::PrintStatusNozzleDiameterMismatch, msg_params);
return false;
}
+1 -1
View File
@@ -2327,7 +2327,7 @@ void SyncAmsInfoDialog::update_show_status()
wxString error_message;
if (!is_nozzle_type_match(*obj_->GetExtderSystem(), error_message)) {
std::vector<wxString> params{error_message};
params.emplace_back(_L("Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting."));
params.emplace_back(_L("Tips: If you changed your nozzle of your printer lately, please go to 'Device -> Printer parts' to change your nozzle setting."));
show_status(PrintDialogStatus::PrintStatusNozzleMatchInvalid, params);
return;
}
+13 -2
View File
@@ -34,6 +34,7 @@
#include "GUI_App.hpp"
#include "GUI_ObjectList.hpp"
#include "slic3r/Utils/PresetUpdater.hpp"
#include "slic3r/plugin/PluginConfig.hpp"
#include "Plater.hpp"
#include "MainFrame.hpp"
#include "format.hpp"
@@ -1795,9 +1796,19 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
// Keep this preset's "plugins" manifest in sync when a plugin picker changes, so full_config() and
// save_to_json() always find resolved "name;uuid;capability" references and rebuild it nowhere else.
// Also drop any plugin_config_overrides entries for a capability the change just stopped
// referencing (e.g. a plugin removed from slicing_pipeline_plugin), so a saved preset never
// carries configuration for a capability it no longer names. The Configure button is a separate
// field holding its own cached copy of that value, so it needs to be told explicitly, or it
// keeps showing the stale count until something else happens to refresh it.
if (const ConfigOptionDef* opt_def = m_config->def()->get(opt_key);
opt_def && opt_def->is_plugin_backed())
opt_def && opt_def->is_plugin_backed()) {
m_config->update_plugin_manifest();
if (prune_stale_plugin_overrides(*m_config)) {
if (Field* overrides_field = get_field(PLUGIN_OVERRIDES_OPTION_KEY))
overrides_field->set_value(boost::any(m_config->opt_string(PLUGIN_OVERRIDES_OPTION_KEY)), false);
}
}
if (opt_key == "gcode_flavor" && m_type == Preset::TYPE_PRINTER) {
if (auto printer_tab = dynamic_cast<TabPrinter*>(this))
@@ -7917,7 +7928,7 @@ bool Tab::validate_filament_temperature_pairs()
if (delta <= rule.max_delta)
continue;
const wxString deg_c = wxString::FromUTF8("℃");
const wxString deg_c = wxString::FromUTF8(u8"\u2103" /* °C */);
const wxString bullet = wxString::FromUTF8("•");
invalid_pairs += wxString::Format(_L(" - %s:\n %s first layer %d %s, other layers %d %s\n %s max delta %d %s, current delta %d %s\n"),
rule.label, bullet, first_temp, deg_c, other_temp, deg_c, bullet, rule.max_delta, deg_c, delta, deg_c);
+10 -6
View File
@@ -264,7 +264,7 @@ TroubleshootDialog::TroubleshootDialog()
});
// PROFILES
auto prf_sys_cache_tip = _L("Cleans and rebuilds system profiles cache on next launch");
auto prf_sys_cache_tip = _L("Cleans and rebuilds system profiles cache on next launch.");
auto prf_sys_cache_szr = create_label(_L("Clean system profiles cache"), prf_sys_cache_tip);
auto prf_sys_cache_btn = create_btn(_L("Clean"), prf_sys_cache_tip);
prf_sys_cache_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) {
@@ -272,8 +272,8 @@ TroubleshootDialog::TroubleshootDialog()
});
prf_sys_cache_szr->Add(prf_sys_cache_btn, 0, wxALIGN_CENTER_VERTICAL);
auto prf_loaded_szr = create_label(_L("Loaded profiles overview"), _L("This section shows information for loaded profiles"));
auto prf_loaded_btn = create_btn(_L("Export") + dots, _L("Exports detailed overview of loaded profiles in json format"));
auto prf_loaded_szr = create_label(_L("Loaded profiles overview"), _L("This section shows information for loaded profiles."));
auto prf_loaded_btn = create_btn(_L("Export") + dots, _L("Exports detailed overview of loaded profiles in json format."));
prf_loaded_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) {
return ExportAsJson(GetProfilesOverview(),"ProfilesOverview");
});
@@ -283,7 +283,7 @@ TroubleshootDialog::TroubleshootDialog()
// MORE
auto cfg_folder_szr = create_label(_L("Configurations folder"), "");
auto cfg_folder_btn = create_btn(_L("Browse") + "...", _L("Opens configurations folder"));
auto cfg_folder_btn = create_btn(_L("Browse") + "...", _L("Opens configurations folder."));
cfg_folder_btn->Bind(wxEVT_BUTTON, [this, data_dir](wxCommandEvent &e) {
BrowseFolder(data_dir.string());
});
@@ -807,7 +807,11 @@ wxString TroubleshootDialog::GetRAMinfo()
wxString TroubleshootDialog::GetGPUinfo()
{
auto gl_info = OpenGLManager::get_gl_info();
return gl_info.get_renderer()+ " GLSL:" + gl_info.get_glsl_version();
#if !SLIC3R_OPENGL_ES
return gl_info.get_renderer() + " GLSL:" + gl_info.get_glsl_version() + (gl_info.is_core_profile() ? " Core" : " Compatibility");
#else
return gl_info.get_renderer() + " GLSL:" + gl_info.get_glsl_version() + " ES";
#endif
}
wxString TroubleshootDialog::GetMONinfo()
@@ -922,7 +926,7 @@ void TroubleshootDialog::PackAll()
auto res = MessageDialog(this,
_L("The current project has unsaved changes. Would you like to save before continuing\?") +
"\n\n" +
_L("Select NO to close dialog and review project"),
_L("Select NO to close dialog and review project."),
wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Save"), wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxCENTRE
).ShowModal();
if (res == wxID_YES)
+1 -1
View File
@@ -1162,7 +1162,7 @@ namespace Slic3r {
switch(ack){
case ElegooLinkStartPrintAck::SDCP_PRINT_CTRL_ACK_BUSY:
{
error_message =_L("The printer is busy, Please check the device page for the file and try to start printing again.");
error_message =_L("The printer is busy, please check the device page for the file and try to start printing again.");
break;
}
case ElegooLinkStartPrintAck::SDCP_PRINT_CTRL_ACK_NOT_FOUND:
+59
View File
@@ -5,6 +5,7 @@
#include <boost/log/trivial.hpp>
#include <boost/nowide/fstream.hpp>
#include <libslic3r/Config.hpp>
#include <libslic3r/PresetBundle.hpp>
#include <libslic3r/PrintConfig.hpp>
#include <slic3r/GUI/GUI.hpp>
@@ -164,6 +165,20 @@ bool CapabilityConfigDocument::erase(const PluginCapabilityId& id)
return erased;
}
bool CapabilityConfigDocument::prune_unreferenced(const std::set<std::pair<PluginCapabilityType, std::string>>& referenced)
{
bool changed = false;
for (auto it = m_entries.begin(); it != m_entries.end();) {
if (referenced.count({it->first.type, it->first.name}) != 0) {
++it;
} else {
it = m_entries.erase(it);
changed = true;
}
}
return changed;
}
bool CapabilityConfigDocument::empty() const
{
return m_entries.empty() && m_opaque_entries.empty();
@@ -342,6 +357,50 @@ std::string serialize_plugin_overrides(const CapabilityConfigDocument& document)
return document.empty() ? std::string() : document.serialize_entries().dump();
}
bool prune_stale_plugin_overrides(DynamicConfig& config)
{
const auto* overrides_opt = dynamic_cast<const ConfigOptionString*>(config.option(PLUGIN_OVERRIDES_OPTION_KEY));
if (overrides_opt == nullptr || overrides_opt->value.empty())
return false;
CapabilityConfigDocument overrides;
std::string error;
if (!parse_plugin_overrides(overrides_opt->value, overrides, error)) {
// Malformed text is not ours to fix up here: leave it untouched rather than risk
// discarding data the user might still be able to recover.
BOOST_LOG_TRIVIAL(error) << "prune_stale_plugin_overrides: " << error;
return false;
}
// Capability names currently referenced by a plugin-backed option's value(s) — e.g.
// slicing_pipeline_plugin's ConfigOptionStrings entries name SlicingPipeline capabilities
// directly, the same raw values save_plugin_collection() resolves into the "plugins" manifest.
std::set<std::pair<PluginCapabilityType, std::string>> referenced;
const ConfigDef* def = config.def();
for (const std::string& opt_key : config.keys()) {
const ConfigOptionDef* opt_def = def != nullptr ? def->get(opt_key) : nullptr;
if (opt_def == nullptr || !opt_def->is_plugin_backed())
continue;
const ConfigOption* opt = config.option(opt_key);
const PluginCapabilityType type = plugin_capability_type_from_string(opt_def->plugin_type);
if (const auto* string_opt = dynamic_cast<const ConfigOptionString*>(opt)) {
if (!string_opt->value.empty())
referenced.emplace(type, string_opt->value);
} else if (const auto* vector_opt = dynamic_cast<const ConfigOptionVectorBase*>(opt)) {
for (const std::string& value : vector_opt->vserialize())
if (!value.empty())
referenced.emplace(type, value);
}
}
if (!overrides.prune_unreferenced(referenced))
return false;
config.set_key_value(PLUGIN_OVERRIDES_OPTION_KEY, new ConfigOptionString(serialize_plugin_overrides(overrides)));
return true;
}
EffectiveCapabilityConfig PresetPluginConfigService::get_effective_config(const CapabilityConfigDocument& overrides,
const PluginCapabilityId& id) const
{
+14
View File
@@ -8,7 +8,9 @@
#include <map>
#include <mutex>
#include <optional>
#include <set>
#include <string>
#include <utility>
#include <vector>
#define PLUGIN_CONFIG_DIR "config.json"
@@ -16,6 +18,7 @@
namespace Slic3r {
class Preset;
class DynamicConfig;
struct CapabilityConfigEntry
{
PluginCapabilityId id;
@@ -35,6 +38,9 @@ public:
bool contains(const PluginCapabilityId& id) const;
bool upsert(CapabilityConfigEntry entry);
bool erase(const PluginCapabilityId& id);
// Drops every entry whose (type, name) is not in `referenced`, e.g. capabilities a preset's
// plugin-backed options no longer name. Returns true if anything was removed.
bool prune_unreferenced(const std::set<std::pair<PluginCapabilityType, std::string>>& referenced);
bool empty() const;
nlohmann::json serialize_entries() const;
nlohmann::json root_json() const;
@@ -50,6 +56,14 @@ std::string plugin_overrides_of(const Preset& preset);
bool parse_plugin_overrides(const std::string& raw, CapabilityConfigDocument& document, std::string& error);
std::string serialize_plugin_overrides(const CapabilityConfigDocument& document);
// Drops plugin_config_overrides entries for capabilities no longer named by any plugin-backed
// option's current value in `config` (e.g. slicing_pipeline_plugin cleared or switched to a
// different capability), and writes the result back if anything changed. Called wherever a
// plugin-backed option's value changes, so a saved preset never carries configuration for a
// capability it no longer references. Returns true if `config` was modified, so a caller holding a
// GUI field over PLUGIN_OVERRIDES_OPTION_KEY knows it must refresh that field's displayed value.
bool prune_stale_plugin_overrides(DynamicConfig& config);
struct EffectiveCapabilityConfig
{
PluginCapabilityId id;