Merge remote-tracking branch 'origin/master' into feature_slice_to_png

This commit is contained in:
tamasmeszaros 2018-07-03 11:40:35 +02:00
commit f00c17b959
11 changed files with 108 additions and 110 deletions

View file

@ -122,6 +122,10 @@ sub _init_tabpanel {
EVT_NOTEBOOK_PAGE_CHANGED($self, $self->{tabpanel}, sub { EVT_NOTEBOOK_PAGE_CHANGED($self, $self->{tabpanel}, sub {
my $panel = $self->{tabpanel}->GetCurrentPage; my $panel = $self->{tabpanel}->GetCurrentPage;
$panel->OnActivate if $panel->can('OnActivate'); $panel->OnActivate if $panel->can('OnActivate');
for my $tab_name (qw(print filament printer)) {
Slic3r::GUI::get_preset_tab("$tab_name")->OnActivate if ("$tab_name" eq $panel->GetName);
}
}); });
if (!$self->{no_plater}) { if (!$self->{no_plater}) {

View file

@ -142,10 +142,10 @@ public:
} }
m_gcode += "G1"; m_gcode += "G1";
if (std::abs(dx) > EPSILON) if (std::abs(rot.x - rotated_current_pos.x) > EPSILON)
m_gcode += set_format_X(rot.x); m_gcode += set_format_X(rot.x);
if (std::abs(dy) > EPSILON) if (std::abs(rot.y - rotated_current_pos.y) > EPSILON)
m_gcode += set_format_Y(rot.y); m_gcode += set_format_Y(rot.y);
if (e != 0.f) if (e != 0.f)

View file

@ -14,7 +14,7 @@
#include <boost/thread.hpp> #include <boost/thread.hpp>
#define SLIC3R_FORK_NAME "Slic3r Prusa Edition" #define SLIC3R_FORK_NAME "Slic3r Prusa Edition"
#define SLIC3R_VERSION "1.40.0" #define SLIC3R_VERSION "1.40.1-rc"
#define SLIC3R_BUILD "UNKNOWN" #define SLIC3R_BUILD "UNKNOWN"
typedef int32_t coord_t; typedef int32_t coord_t;

View file

@ -893,9 +893,9 @@ const wxString& ConfigWizard::name()
{ {
// A different naming convention is used for the Wizard on Windows vs. OSX & GTK. // A different naming convention is used for the Wizard on Windows vs. OSX & GTK.
#if WIN32 #if WIN32
static const wxString config_wizard_name = _(L("Configuration Wizard")); static const wxString config_wizard_name = L("Configuration Wizard");
#else #else
static const wxString config_wizard_name = _(L("Configuration Assistant")); static const wxString config_wizard_name = L("Configuration Assistant");
#endif #endif
return config_wizard_name; return config_wizard_name;
} }

View file

@ -317,9 +317,10 @@ void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_l
auto local_menu = new wxMenu(); auto local_menu = new wxMenu();
wxWindowID config_id_base = wxWindow::NewControlId((int)ConfigMenuCnt); wxWindowID config_id_base = wxWindow::NewControlId((int)ConfigMenuCnt);
const auto config_wizard_tooltip = wxString::Format(_(L("Run %s")), ConfigWizard::name()); auto config_wizard_name = _(ConfigWizard::name().wx_str());
const auto config_wizard_tooltip = wxString::Format(_(L("Run %s")), config_wizard_name);
// Cmd+, is standard on OS X - what about other operating systems? // Cmd+, is standard on OS X - what about other operating systems?
local_menu->Append(config_id_base + ConfigMenuWizard, ConfigWizard::name() + dots, config_wizard_tooltip); local_menu->Append(config_id_base + ConfigMenuWizard, config_wizard_name + dots, config_wizard_tooltip);
local_menu->Append(config_id_base + ConfigMenuSnapshots, _(L("Configuration Snapshots"))+dots, _(L("Inspect / activate configuration snapshots"))); local_menu->Append(config_id_base + ConfigMenuSnapshots, _(L("Configuration Snapshots"))+dots, _(L("Inspect / activate configuration snapshots")));
local_menu->Append(config_id_base + ConfigMenuTakeSnapshot, _(L("Take Configuration Snapshot")), _(L("Capture a configuration snapshot"))); local_menu->Append(config_id_base + ConfigMenuTakeSnapshot, _(L("Take Configuration Snapshot")), _(L("Capture a configuration snapshot")));
// local_menu->Append(config_id_base + ConfigMenuUpdate, _(L("Check for updates")), _(L("Check for configuration updates"))); // local_menu->Append(config_id_base + ConfigMenuUpdate, _(L("Check for updates")), _(L("Check for configuration updates")));

View file

@ -40,49 +40,30 @@ void Tab::create_preset_tab(PresetBundle *preset_bundle)
m_preset_bundle = preset_bundle; m_preset_bundle = preset_bundle;
// Vertical sizer to hold the choice menu and the rest of the page. // Vertical sizer to hold the choice menu and the rest of the page.
#ifdef __WXOSX__
auto *main_sizer = new wxBoxSizer(wxVERTICAL);
main_sizer->SetSizeHints(this);
this->SetSizer(main_sizer);
// Create additional panel to Fit() it from OnActivate()
// It's needed for tooltip showing on OSX
m_tmp_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL);
auto panel = m_tmp_panel;
auto sizer = new wxBoxSizer(wxVERTICAL);
m_tmp_panel->SetSizer(sizer);
m_tmp_panel->Layout();
main_sizer->Add(m_tmp_panel, 1, wxEXPAND | wxALL, 0);
#else
Tab *panel = this; Tab *panel = this;
auto *sizer = new wxBoxSizer(wxVERTICAL); auto *sizer = new wxBoxSizer(wxVERTICAL);
sizer->SetSizeHints(panel); sizer->SetSizeHints(panel);
panel->SetSizer(sizer); panel->SetSizer(sizer);
#endif //__WXOSX__
// preset chooser // preset chooser
m_presets_choice = new wxBitmapComboBox(panel, wxID_ANY, "", wxDefaultPosition, wxSize(270, -1), 0, 0,wxCB_READONLY); m_presets_choice = new wxBitmapComboBox(panel, wxID_ANY, "", wxDefaultPosition, wxSize(270, -1), 0, 0,wxCB_READONLY);
/*
m_cc_presets_choice = new wxComboCtrl(panel, wxID_ANY, L(""), wxDefaultPosition, wxDefaultSize, wxCB_READONLY);
wxDataViewTreeCtrlComboPopup* popup = new wxDataViewTreeCtrlComboPopup;
if (popup != nullptr)
{
// FIXME If the following line is removed, the combo box popup list will not react to mouse clicks.
// On the other side, with this line the combo box popup cannot be closed by clicking on the combo button on Windows 10.
// m_cc_presets_choice->UseAltPopupWindow();
// m_cc_presets_choice->EnablePopupAnimation(false);
m_cc_presets_choice->SetPopupControl(popup);
popup->SetStringValue(from_u8("Text1"));
popup->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [this, popup](wxCommandEvent& evt)
{
auto selected = popup->GetItemText(popup->GetSelection());
if (selected != _(L("System presets")) && selected != _(L("Default presets")))
{
m_cc_presets_choice->SetText(selected);
std::string selected_string = selected.ToUTF8().data();
#ifdef __APPLE__
#else
select_preset(selected_string);
#endif
}
});
// popup->Bind(wxEVT_KEY_DOWN, [popup](wxKeyEvent& evt) { popup->OnKeyEvent(evt); });
// popup->Bind(wxEVT_KEY_UP, [popup](wxKeyEvent& evt) { popup->OnKeyEvent(evt); });
auto icons = new wxImageList(16, 16, true, 1);
popup->SetImageList(icons);
icons->Add(*new wxIcon(from_u8(Slic3r::var("flag-green-icon.png")), wxBITMAP_TYPE_PNG));
icons->Add(*new wxIcon(from_u8(Slic3r::var("flag-red-icon.png")), wxBITMAP_TYPE_PNG));
}
*/
auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
//buttons //buttons
@ -173,37 +154,6 @@ void Tab::create_preset_tab(PresetBundle *preset_bundle)
m_hsizer = new wxBoxSizer(wxHORIZONTAL); m_hsizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(m_hsizer, 1, wxEXPAND, 0); sizer->Add(m_hsizer, 1, wxEXPAND, 0);
/*
//temporary left vertical sizer
m_left_sizer = new wxBoxSizer(wxVERTICAL);
m_hsizer->Add(m_left_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, 3);
// tree
m_presetctrl = new wxDataViewTreeCtrl(panel, wxID_ANY, wxDefaultPosition, wxSize(200, -1), wxDV_NO_HEADER);
m_left_sizer->Add(m_presetctrl, 1, wxEXPAND);
m_preset_icons = new wxImageList(16, 16, true, 1);
m_presetctrl->SetImageList(m_preset_icons);
m_preset_icons->Add(*new wxIcon(from_u8(Slic3r::var("flag-green-icon.png")), wxBITMAP_TYPE_PNG));
m_preset_icons->Add(*new wxIcon(from_u8(Slic3r::var("flag-red-icon.png")), wxBITMAP_TYPE_PNG));
m_presetctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [this](wxCommandEvent& evt)
{
auto selected = m_presetctrl->GetItemText(m_presetctrl->GetSelection());
if (selected != _(L("System presets")) && selected != _(L("Default presets")))
{
std::string selected_string = selected.ToUTF8().data();
#ifdef __APPLE__
#else
select_preset(selected_string);
#endif
}
});
*/
//left vertical sizer //left vertical sizer
m_left_sizer = new wxBoxSizer(wxVERTICAL); m_left_sizer = new wxBoxSizer(wxVERTICAL);
m_hsizer->Add(m_left_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, 3); m_hsizer->Add(m_left_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, 3);
@ -233,7 +183,7 @@ void Tab::create_preset_tab(PresetBundle *preset_bundle)
return; return;
if (selected_item >= 0){ if (selected_item >= 0){
std::string selected_string = m_presets_choice->GetString(selected_item).ToUTF8().data(); std::string selected_string = m_presets_choice->GetString(selected_item).ToUTF8().data();
if (selected_string.find_first_of("-------") == 0 if (selected_string.find("-------") == 0
/*selected_string == "------- System presets -------" || /*selected_string == "------- System presets -------" ||
selected_string == "------- User presets -------"*/){ selected_string == "------- User presets -------"*/){
m_presets_choice->SetSelection(m_selected_preset_item); m_presets_choice->SetSelection(m_selected_preset_item);
@ -279,7 +229,12 @@ PageShp Tab::add_options_page(const wxString& title, const std::string& icon, bo
} }
} }
// Initialize the page. // Initialize the page.
PageShp page(new Page(this, title, icon_idx)); #ifdef __WXOSX__
auto panel = m_tmp_panel;
#else
auto panel = this;
#endif
PageShp page(new Page(panel, title, icon_idx));
page->SetScrollbars(1, 1, 1, 1); page->SetScrollbars(1, 1, 1, 1);
page->Hide(); page->Hide();
m_hsizer->Add(page.get(), 1, wxEXPAND | wxLEFT, 5); m_hsizer->Add(page.get(), 1, wxEXPAND | wxLEFT, 5);
@ -290,6 +245,18 @@ PageShp Tab::add_options_page(const wxString& title, const std::string& icon, bo
return page; return page;
} }
void Tab::OnActivate()
{
#ifdef __WXOSX__
wxWindowUpdateLocker noUpdates(this);
auto size = GetSizer()->GetSize();
m_tmp_panel->GetSizer()->SetMinSize(size.x + m_size_move, size.y);
Fit();
m_size_move *= -1;
#endif // __WXOSX__
}
void Tab::update_labels_colour() void Tab::update_labels_colour()
{ {
Freeze(); Freeze();
@ -487,8 +454,13 @@ void Tab::update_changed_tree_ui()
get_sys_and_mod_flags(opt_key, sys_page, modified_page); get_sys_and_mod_flags(opt_key, sys_page, modified_page);
} }
} }
if (title == _("Dependencies") && name() != "printer"){ if (title == _("Dependencies")){
if (name() != "printer")
get_sys_and_mod_flags("compatible_printers", sys_page, modified_page); get_sys_and_mod_flags("compatible_printers", sys_page, modified_page);
else {
sys_page = m_presets->get_selected_preset_parent() ? true:false;
modified_page = false;
}
} }
for (auto group : page->m_optgroups) for (auto group : page->m_optgroups)
{ {
@ -1248,6 +1220,7 @@ void TabPrint::OnActivate()
{ {
m_recommended_thin_wall_thickness_description_line->SetText( m_recommended_thin_wall_thickness_description_line->SetText(
from_u8(PresetHints::recommended_thin_wall_thickness(*m_preset_bundle))); from_u8(PresetHints::recommended_thin_wall_thickness(*m_preset_bundle)));
Tab::OnActivate();
} }
void TabFilament::build() void TabFilament::build()
@ -1405,6 +1378,7 @@ void TabFilament::update()
void TabFilament::OnActivate() void TabFilament::OnActivate()
{ {
m_volumetric_speed_description_line->SetText(from_u8(PresetHints::maximum_volumetric_flow_description(*m_preset_bundle))); m_volumetric_speed_description_line->SetText(from_u8(PresetHints::maximum_volumetric_flow_description(*m_preset_bundle)));
Tab::OnActivate();
} }
wxSizer* Tab::description_line_widget(wxWindow* parent, ogStaticText* *StaticText) wxSizer* Tab::description_line_widget(wxWindow* parent, ogStaticText* *StaticText)
@ -1894,6 +1868,8 @@ void Tab::load_current_preset()
m_ttg_non_system = m_presets->get_selected_preset_parent() ? &m_ttg_value_unlock : &m_ttg_white_bullet_ns; m_ttg_non_system = m_presets->get_selected_preset_parent() ? &m_ttg_value_unlock : &m_ttg_white_bullet_ns;
m_tt_non_system = m_presets->get_selected_preset_parent() ? &m_tt_value_unlock : &m_ttg_white_bullet_ns; m_tt_non_system = m_presets->get_selected_preset_parent() ? &m_tt_value_unlock : &m_ttg_white_bullet_ns;
m_undo_to_sys_btn->Enable(!preset.is_default);
// use CallAfter because some field triggers schedule on_change calls using CallAfter, // use CallAfter because some field triggers schedule on_change calls using CallAfter,
// and we don't want them to be called after this update_dirty() as they would mark the // and we don't want them to be called after this update_dirty() as they would mark the
// preset dirty again // preset dirty again
@ -2560,28 +2536,33 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la
if (noncommon_label_width >= 0) if (noncommon_label_width >= 0)
optgroup->label_width = noncommon_label_width; optgroup->label_width = noncommon_label_width;
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ #ifdef __WXOSX__
auto tab = GetParent()->GetParent();
#else
auto tab = GetParent();
#endif
optgroup->m_on_change = [this, tab](t_config_option_key opt_key, boost::any value){
//! This function will be called from OptionGroup. //! This function will be called from OptionGroup.
//! Using of CallAfter is redundant. //! Using of CallAfter is redundant.
//! And in some cases it causes update() function to be recalled again //! And in some cases it causes update() function to be recalled again
//! wxTheApp->CallAfter([this, opt_key, value]() { //! wxTheApp->CallAfter([this, opt_key, value]() {
static_cast<Tab*>(GetParent())->update_dirty(); static_cast<Tab*>(tab)->update_dirty();
static_cast<Tab*>(GetParent())->on_value_change(opt_key, value); static_cast<Tab*>(tab)->on_value_change(opt_key, value);
//! }); //! });
}; };
optgroup->m_get_initial_config = [this](){ optgroup->m_get_initial_config = [this, tab](){
DynamicPrintConfig config = static_cast<Tab*>(GetParent())->m_presets->get_selected_preset().config; DynamicPrintConfig config = static_cast<Tab*>(tab)->m_presets->get_selected_preset().config;
return config; return config;
}; };
optgroup->m_get_sys_config = [this](){ optgroup->m_get_sys_config = [this, tab](){
DynamicPrintConfig config = static_cast<Tab*>(GetParent())->m_presets->get_selected_preset_parent()->config; DynamicPrintConfig config = static_cast<Tab*>(tab)->m_presets->get_selected_preset_parent()->config;
return config; return config;
}; };
optgroup->have_sys_config = [this](){ optgroup->have_sys_config = [this, tab](){
return static_cast<Tab*>(GetParent())->m_presets->get_selected_preset_parent() != nullptr; return static_cast<Tab*>(tab)->m_presets->get_selected_preset_parent() != nullptr;
}; };
vsizer()->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 10); vsizer()->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 10);

View file

@ -102,6 +102,10 @@ using PageShp = std::shared_ptr<Page>;
class Tab: public wxPanel class Tab: public wxPanel
{ {
wxNotebook* m_parent; wxNotebook* m_parent;
#ifdef __WXOSX__
wxPanel* m_tmp_panel;
int m_size_move = -1;
#endif // __WXOSX__
protected: protected:
std::string m_name; std::string m_name;
const wxString m_title; const wxString m_title;
@ -118,7 +122,6 @@ protected:
wxButton* m_undo_btn; wxButton* m_undo_btn;
wxButton* m_undo_to_sys_btn; wxButton* m_undo_to_sys_btn;
wxButton* m_question_btn; wxButton* m_question_btn;
wxComboCtrl* m_cc_presets_choice; wxComboCtrl* m_cc_presets_choice;
wxDataViewTreeCtrl* m_presetctrl; wxDataViewTreeCtrl* m_presetctrl;
wxImageList* m_preset_icons; wxImageList* m_preset_icons;
@ -198,7 +201,7 @@ public:
Tab() {} Tab() {}
Tab(wxNotebook* parent, const wxString& title, const char* name, bool no_controller) : Tab(wxNotebook* parent, const wxString& title, const char* name, bool no_controller) :
m_parent(parent), m_title(title), m_name(name), m_no_controller(no_controller) { m_parent(parent), m_title(title), m_name(name), m_no_controller(no_controller) {
Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL); Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL, name);
get_tabs_list().push_back(this); get_tabs_list().push_back(this);
} }
~Tab(){ ~Tab(){
@ -242,7 +245,7 @@ public:
PageShp add_options_page(const wxString& title, const std::string& icon, bool is_extruder_pages = false); PageShp add_options_page(const wxString& title, const std::string& icon, bool is_extruder_pages = false);
virtual void OnActivate(){} virtual void OnActivate();
virtual void on_preset_loaded(){} virtual void on_preset_loaded(){}
virtual void build() = 0; virtual void build() = 0;
virtual void update() = 0; virtual void update() = 0;

View file

@ -202,7 +202,6 @@ std::string Http::priv::body_size_error()
void Http::priv::http_perform() void Http::priv::http_perform()
{ {
::curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); ::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writecb); ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writecb);
::curl_easy_setopt(curl, CURLOPT_WRITEDATA, static_cast<void*>(this)); ::curl_easy_setopt(curl, CURLOPT_WRITEDATA, static_cast<void*>(this));
@ -231,8 +230,6 @@ void Http::priv::http_perform()
} }
CURLcode res = ::curl_easy_perform(curl); CURLcode res = ::curl_easy_perform(curl);
long http_status = 0;
::curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_status);
if (res != CURLE_OK) { if (res != CURLE_OK) {
if (res == CURLE_ABORTED_BY_CALLBACK) { if (res == CURLE_ABORTED_BY_CALLBACK) {
@ -243,17 +240,22 @@ void Http::priv::http_perform()
if (progressfn) { progressfn(dummyprogress, cancel); } if (progressfn) { progressfn(dummyprogress, cancel); }
} else { } else {
// The abort comes from the CURLOPT_READFUNCTION callback, which means reading file failed // The abort comes from the CURLOPT_READFUNCTION callback, which means reading file failed
if (errorfn) { errorfn(std::move(buffer), "Error reading file for file upload", http_status); } if (errorfn) { errorfn(std::move(buffer), "Error reading file for file upload", 0); }
} }
} }
else if (res == CURLE_WRITE_ERROR) { else if (res == CURLE_WRITE_ERROR) {
if (errorfn) { errorfn(std::move(buffer), body_size_error(), http_status); } if (errorfn) { errorfn(std::move(buffer), body_size_error(), 0); }
} else { } else {
if (errorfn) { errorfn(std::move(buffer), curl_error(res), http_status); } if (errorfn) { errorfn(std::move(buffer), curl_error(res), 0); }
}; };
} else { } else {
if (completefn) { long http_status = 0;
completefn(std::move(buffer), http_status); ::curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_status);
if (http_status >= 400) {
if (errorfn) { errorfn(std::move(buffer), std::string(), http_status); }
} else {
if (completefn) { completefn(std::move(buffer), http_status); }
} }
} }
} }

View file

@ -29,7 +29,16 @@ public:
typedef std::shared_ptr<Http> Ptr; typedef std::shared_ptr<Http> Ptr;
typedef std::function<void(std::string /* body */, unsigned /* http_status */)> CompleteFn; typedef std::function<void(std::string /* body */, unsigned /* http_status */)> CompleteFn;
// A HTTP request may fail at various stages of completeness (URL parsing, DNS lookup, TCP connection, ...).
// If the HTTP request could not be made or failed before completion, the `error` arg contains a description
// of the error and `http_status` is zero.
// If the HTTP request was completed but the response HTTP code is >= 400, `error` is empty and `http_status` contains the response code.
// In either case there may or may not be a body.
typedef std::function<void(std::string /* body */, std::string /* error */, unsigned /* http_status */)> ErrorFn; typedef std::function<void(std::string /* body */, std::string /* error */, unsigned /* http_status */)> ErrorFn;
// See the Progress struct above.
// Writing true to the `cancel` reference cancels the request in progress.
typedef std::function<void(Progress, bool& /* cancel */)> ProgressFn; typedef std::function<void(Progress, bool& /* cancel */)> ProgressFn;
Http(Http &&other); Http(Http &&other);

View file

@ -78,10 +78,10 @@ bool OctoPrint::test(wxString &msg) const
auto http = Http::get(std::move(url)); auto http = Http::get(std::move(url));
set_auth(http); set_auth(http);
http.on_error([&](std::string, std::string error, unsigned status) { http.on_error([&](std::string body, std::string error, unsigned status) {
BOOST_LOG_TRIVIAL(error) << boost::format("Octoprint: Error getting version: %1% (HTTP %2%)") % error % status; BOOST_LOG_TRIVIAL(error) << boost::format("Octoprint: Error getting version: %1%, HTTP %2%, body: `%3%`") % error % status % body;
res = false; res = false;
msg = format_error(error, status); msg = format_error(body, error, status);
}) })
.on_complete([&](std::string body, unsigned) { .on_complete([&](std::string body, unsigned) {
BOOST_LOG_TRIVIAL(debug) << boost::format("Octoprint: Got version: %1%") % body; BOOST_LOG_TRIVIAL(debug) << boost::format("Octoprint: Got version: %1%") % body;
@ -140,8 +140,8 @@ bool OctoPrint::send_gcode(const std::string &filename) const
progress_dialog.Update(PROGRESS_RANGE); progress_dialog.Update(PROGRESS_RANGE);
}) })
.on_error([&](std::string body, std::string error, unsigned status) { .on_error([&](std::string body, std::string error, unsigned status) {
BOOST_LOG_TRIVIAL(error) << boost::format("Octoprint: Error uploading file: %1% (HTTP %2%)") % error % status; BOOST_LOG_TRIVIAL(error) << boost::format("Octoprint: Error uploading file: %1%, HTTP %2%, body: `%3%`") % error % status % body;
auto errormsg = wxString::Format("%s: %s", errortitle, format_error(error, status)); auto errormsg = wxString::Format("%s: %s", errortitle, format_error(body, error, status));
GUI::show_error(&progress_dialog, std::move(errormsg)); GUI::show_error(&progress_dialog, std::move(errormsg));
res = false; res = false;
}) })
@ -183,15 +183,13 @@ std::string OctoPrint::make_url(const std::string &path) const
} }
} }
wxString OctoPrint::format_error(const std::string &error, unsigned status) wxString OctoPrint::format_error(const std::string &body, const std::string &error, unsigned status)
{ {
auto wxerror = wxString::FromUTF8(error.data());
if (status != 0) { if (status != 0) {
return wxString::Format("HTTP %u: %s", status, auto wxbody = wxString::FromUTF8(body.data());
(status == 401 ? _(L("Invalid API key")) : wxerror)); return wxString::Format("HTTP %u: %s", status, wxbody);
} else { } else {
return wxerror; return wxString::FromUTF8(error.data());
} }
} }

View file

@ -26,7 +26,7 @@ private:
void set_auth(Http &http) const; void set_auth(Http &http) const;
std::string make_url(const std::string &path) const; std::string make_url(const std::string &path) const;
static wxString format_error(const std::string &error, unsigned status); static wxString format_error(const std::string &body, const std::string &error, unsigned status);
}; };