Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_world_coordinates

This commit is contained in:
enricoturri1966 2021-11-11 15:25:48 +01:00
commit 1dadc4f90d
23 changed files with 199 additions and 146 deletions

View File

@ -4752,7 +4752,7 @@ exposure_time = 10
initial_exposure_time = 20 initial_exposure_time = 20
material_type = Tough material_type = Tough
material_vendor = Harz Labs material_vendor = Harz Labs
material_colour = #007EFD material_colour = #595959
[sla_material:Harz Labs Dental Cast Red @0.025] [sla_material:Harz Labs Dental Cast Red @0.025]
inherits = *common 0.025* inherits = *common 0.025*
@ -4768,7 +4768,7 @@ exposure_time = 6
initial_exposure_time = 30 initial_exposure_time = 30
material_type = Tough material_type = Tough
material_vendor = Esun material_vendor = Esun
material_colour = #007EFD material_colour = #595959
[sla_material:Photocentric Ash Grey @0.025] [sla_material:Photocentric Ash Grey @0.025]
inherits = *common 0.025* inherits = *common 0.025*
@ -4800,7 +4800,7 @@ exposure_time = 4
initial_exposure_time = 35 initial_exposure_time = 35
material_type = Tough material_type = Tough
material_vendor = Monocure material_vendor = Monocure
material_colour = #007EFD material_colour = #595959
[sla_material:Monocure 3D Blue Rapid Resin @0.025] [sla_material:Monocure 3D Blue Rapid Resin @0.025]
inherits = *common 0.025* inherits = *common 0.025*
@ -4826,7 +4826,7 @@ exposure_time = 5
initial_exposure_time = 35 initial_exposure_time = 35
material_type = Tough material_type = Tough
material_vendor = Prusa Polymers material_vendor = Prusa Polymers
material_colour = #007EFD material_colour = #595959
[sla_material:Prusament Resin Tough Anthracite Grey @0.025] [sla_material:Prusament Resin Tough Anthracite Grey @0.025]
inherits = *common 0.025* inherits = *common 0.025*
@ -4995,7 +4995,7 @@ exposure_time = 5
initial_exposure_time = 35 initial_exposure_time = 35
material_type = Tough material_type = Tough
material_vendor = Made for Prusa material_vendor = Made for Prusa
material_colour = #007EFD material_colour = #595959
[sla_material:Prusa Deep Blue Transparent Tough @0.025] [sla_material:Prusa Deep Blue Transparent Tough @0.025]
inherits = *common 0.025* inherits = *common 0.025*
@ -5131,7 +5131,7 @@ exposure_time = 4
initial_exposure_time = 35 initial_exposure_time = 35
material_type = Tough material_type = Tough
material_vendor = Zortrax material_vendor = Zortrax
material_colour = #007EFD material_colour = #595959
########### Materials 0.05 ########### Materials 0.05
@ -5253,7 +5253,7 @@ exposure_time = 6
initial_exposure_time = 35 initial_exposure_time = 35
material_type = Tough material_type = Tough
material_vendor = Monocure material_vendor = Monocure
material_colour = #007EFD material_colour = #595959
[sla_material:Monocure 3D Blue Rapid Resin @0.05] [sla_material:Monocure 3D Blue Rapid Resin @0.05]
inherits = *common 0.05* inherits = *common 0.05*
@ -5309,7 +5309,7 @@ exposure_time = 7
initial_exposure_time = 30 initial_exposure_time = 30
material_type = Tough material_type = Tough
material_vendor = Esun material_vendor = Esun
material_colour = #007EFD material_colour = #595959
[sla_material:FunToDo Castable Blend Red @0.05] [sla_material:FunToDo Castable Blend Red @0.05]
inherits = *common 0.05* inherits = *common 0.05*
@ -5349,7 +5349,7 @@ exposure_time = 20
initial_exposure_time = 40 initial_exposure_time = 40
material_type = Tough material_type = Tough
material_vendor = 3DM material_vendor = 3DM
material_colour = #007EFD material_colour = #595959
[sla_material:3DM-DENT @0.05] [sla_material:3DM-DENT @0.05]
inherits = *common 0.05* inherits = *common 0.05*
@ -5429,7 +5429,7 @@ exposure_time = 13
initial_exposure_time = 20 initial_exposure_time = 20
material_type = Tough material_type = Tough
material_vendor = Harz Labs material_vendor = Harz Labs
material_colour = #007EFD material_colour = #595959
[sla_material:Harz Labs Dental Cast Red @0.05] [sla_material:Harz Labs Dental Cast Red @0.05]
inherits = *common 0.05* inherits = *common 0.05*
@ -5533,7 +5533,7 @@ exposure_time = 9
initial_exposure_time = 35 initial_exposure_time = 35
material_type = Tough material_type = Tough
material_vendor = Siraya Tech material_vendor = Siraya Tech
material_colour = #007EFD material_colour = #595959
[sla_material:NextDent Model 2.0 Grey @0.05] [sla_material:NextDent Model 2.0 Grey @0.05]
inherits = *common 0.05* inherits = *common 0.05*
@ -5621,7 +5621,7 @@ exposure_time = 7
initial_exposure_time = 35 initial_exposure_time = 35
material_type = Tough material_type = Tough
material_vendor = Zortrax material_vendor = Zortrax
material_colour = #007EFD material_colour = #595959
## Prusa Polymers 0.05 ## Prusa Polymers 0.05
@ -5639,7 +5639,7 @@ exposure_time = 6
initial_exposure_time = 35 initial_exposure_time = 35
material_type = Tough material_type = Tough
material_vendor = Prusa Polymers material_vendor = Prusa Polymers
material_colour = #007EFD material_colour = #595959
[sla_material:Prusament Resin Tough Anthracite Grey @0.05] [sla_material:Prusament Resin Tough Anthracite Grey @0.05]
inherits = *common 0.05* inherits = *common 0.05*
@ -5681,7 +5681,7 @@ exposure_time = 6
initial_exposure_time = 35 initial_exposure_time = 35
material_type = Tough material_type = Tough
material_vendor = Made for Prusa material_vendor = Made for Prusa
material_colour = #007EFD material_colour = #595959
## [sla_material:Prusa Super Low Odor Beige Tough @0.05] ## [sla_material:Prusa Super Low Odor Beige Tough @0.05]
## inherits = *common 0.05* ## inherits = *common 0.05*
@ -5901,7 +5901,7 @@ exposure_time = 8
initial_exposure_time = 35 initial_exposure_time = 35
material_type = Tough material_type = Tough
material_vendor = Made for Prusa material_vendor = Made for Prusa
material_colour = #007EFD material_colour = #595959
[sla_material:Prusa Deep Blue Transparent Tough @0.05] [sla_material:Prusa Deep Blue Transparent Tough @0.05]
inherits = *common 0.05* inherits = *common 0.05*
@ -5955,7 +5955,7 @@ exposure_time = 13
initial_exposure_time = 45 initial_exposure_time = 45
material_type = Tough material_type = Tough
material_vendor = Prusa Polymers material_vendor = Prusa Polymers
material_colour = #007EFD material_colour = #595959
[sla_material:Prusament Resin Tough Anthracite Grey @0.1] [sla_material:Prusament Resin Tough Anthracite Grey @0.1]
inherits = *common 0.1* inherits = *common 0.1*
@ -6021,7 +6021,7 @@ exposure_time = 13
initial_exposure_time = 55 initial_exposure_time = 55
material_type = Tough material_type = Tough
material_vendor = Made for Prusa material_vendor = Made for Prusa
material_colour = #007EFD material_colour = #595959
[sla_material:Prusa Transparent Tough @0.1] [sla_material:Prusa Transparent Tough @0.1]
inherits = *common 0.1* inherits = *common 0.1*
@ -6075,7 +6075,7 @@ exposure_time = 1.8
initial_exposure_time = 25 initial_exposure_time = 25
material_type = Tough material_type = Tough
material_vendor = Prusa Polymers material_vendor = Prusa Polymers
material_colour = #007EFD material_colour = #595959
[sla_material:Prusament Resin Tough Anthracite Grey @0.025 SL1S] [sla_material:Prusament Resin Tough Anthracite Grey @0.025 SL1S]
inherits = *0.025_sl1s* inherits = *0.025_sl1s*
@ -6117,7 +6117,7 @@ exposure_time = 2
initial_exposure_time = 25 initial_exposure_time = 25
material_type = Tough material_type = Tough
material_vendor = Made for Prusa material_vendor = Made for Prusa
material_colour = #007EFD material_colour = #595959
[sla_material:Prusa Cyan Tough @0.025 SL1S] [sla_material:Prusa Cyan Tough @0.025 SL1S]
inherits = *0.025_sl1s* inherits = *0.025_sl1s*
@ -6321,7 +6321,7 @@ exposure_time = 2
initial_exposure_time = 25 initial_exposure_time = 25
material_type = Tough material_type = Tough
material_vendor = Prusa Polymers material_vendor = Prusa Polymers
material_colour = #007EFD material_colour = #595959
[sla_material:Prusament Resin Tough Anthracite Grey @0.05 SL1S] [sla_material:Prusament Resin Tough Anthracite Grey @0.05 SL1S]
inherits = *0.05_sl1s* inherits = *0.05_sl1s*
@ -6363,7 +6363,7 @@ exposure_time = 2.4
initial_exposure_time = 25 initial_exposure_time = 25
material_type = Tough material_type = Tough
material_vendor = Made for Prusa material_vendor = Made for Prusa
material_colour = #007EFD material_colour = #595959
[sla_material:Prusa Cyan Tough @0.05 SL1S] [sla_material:Prusa Cyan Tough @0.05 SL1S]
inherits = *0.05_sl1s* inherits = *0.05_sl1s*
@ -6567,7 +6567,7 @@ exposure_time = 2.6
initial_exposure_time = 25 initial_exposure_time = 25
material_type = Tough material_type = Tough
material_vendor = Prusa Polymers material_vendor = Prusa Polymers
material_colour = #007EFD material_colour = #595959
[sla_material:Prusament Resin Tough Anthracite Grey @0.1 SL1S] [sla_material:Prusament Resin Tough Anthracite Grey @0.1 SL1S]
inherits = *0.1_sl1s* inherits = *0.1_sl1s*
@ -6609,7 +6609,7 @@ exposure_time = 3
initial_exposure_time = 25 initial_exposure_time = 25
material_type = Tough material_type = Tough
material_vendor = Made for Prusa material_vendor = Made for Prusa
material_colour = #007EFD material_colour = #595959
[sla_material:Prusa Cyan Tough @0.1 SL1S] [sla_material:Prusa Cyan Tough @0.1 SL1S]
inherits = *0.1_sl1s* inherits = *0.1_sl1s*

View File

@ -71,8 +71,6 @@ void AppConfig::set_defaults()
if (get("drop_project_action").empty()) if (get("drop_project_action").empty())
set("drop_project_action", "1"); set("drop_project_action", "1");
if (get("version_check").empty())
set("version_check", "1");
if (get("preset_update").empty()) if (get("preset_update").empty())
set("preset_update", "1"); set("preset_update", "1");

View File

@ -1893,7 +1893,7 @@ size_t ModelVolume::split(unsigned int max_extruders)
// discard volumes for which the convex hull was not generated or is degenerate // discard volumes for which the convex hull was not generated or is degenerate
size_t i = 0; size_t i = 0;
while (i < this->object->volumes.size()) { while (i < this->object->volumes.size()) {
std::shared_ptr<const TriangleMesh> hull = this->object->volumes[i]->get_convex_hull_shared_ptr(); const std::shared_ptr<const TriangleMesh> &hull = this->object->volumes[i]->get_convex_hull_shared_ptr();
if (hull == nullptr || hull->its.vertices.empty() || hull->its.indices.empty()) { if (hull == nullptr || hull->its.vertices.empty() || hull->its.indices.empty()) {
this->object->delete_volume(i); this->object->delete_volume(i);
--idx; --idx;

View File

@ -684,7 +684,7 @@ public:
void calculate_convex_hull(); void calculate_convex_hull();
const TriangleMesh& get_convex_hull() const; const TriangleMesh& get_convex_hull() const;
std::shared_ptr<const TriangleMesh> get_convex_hull_shared_ptr() const { return m_convex_hull; } const std::shared_ptr<const TriangleMesh>& get_convex_hull_shared_ptr() const { return m_convex_hull; }
// Get count of errors in the mesh // Get count of errors in the mesh
int get_repaired_errors_count() const; int get_repaired_errors_count() const;

View File

@ -1190,11 +1190,11 @@ std::vector<indexed_triangle_set> its_split(const indexed_triangle_set &its)
} }
// Number of disconnected patches (faces are connected if they share an edge, shared edge defined with 2 shared vertex indices). // Number of disconnected patches (faces are connected if they share an edge, shared edge defined with 2 shared vertex indices).
bool its_number_of_patches(const indexed_triangle_set &its) size_t its_number_of_patches(const indexed_triangle_set &its)
{ {
return its_number_of_patches<>(its); return its_number_of_patches<>(its);
} }
bool its_number_of_patches(const indexed_triangle_set &its, const std::vector<Vec3i> &face_neighbors) size_t its_number_of_patches(const indexed_triangle_set &its, const std::vector<Vec3i> &face_neighbors)
{ {
return its_number_of_patches<>(ItsNeighborsWrapper{ its, face_neighbors }); return its_number_of_patches<>(ItsNeighborsWrapper{ its, face_neighbors });
} }

View File

@ -219,8 +219,8 @@ std::vector<indexed_triangle_set> its_split(const indexed_triangle_set &its);
std::vector<indexed_triangle_set> its_split(const indexed_triangle_set &its, std::vector<Vec3i> &face_neighbors); std::vector<indexed_triangle_set> its_split(const indexed_triangle_set &its, std::vector<Vec3i> &face_neighbors);
// Number of disconnected patches (faces are connected if they share an edge, shared edge defined with 2 shared vertex indices). // Number of disconnected patches (faces are connected if they share an edge, shared edge defined with 2 shared vertex indices).
bool its_number_of_patches(const indexed_triangle_set &its); size_t its_number_of_patches(const indexed_triangle_set &its);
bool its_number_of_patches(const indexed_triangle_set &its, const std::vector<Vec3i> &face_neighbors); size_t its_number_of_patches(const indexed_triangle_set &its, const std::vector<Vec3i> &face_neighbors);
// Same as its_number_of_patches(its) > 1, but faster. // Same as its_number_of_patches(its) > 1, but faster.
bool its_is_splittable(const indexed_triangle_set &its); bool its_is_splittable(const indexed_triangle_set &its);
bool its_is_splittable(const indexed_triangle_set &its, const std::vector<Vec3i> &face_neighbors); bool its_is_splittable(const indexed_triangle_set &its, const std::vector<Vec3i> &face_neighbors);

View File

@ -1206,7 +1206,7 @@ PageUpdate::PageUpdate(ConfigWizard *parent)
boldfont.SetWeight(wxFONTWEIGHT_BOLD); boldfont.SetWeight(wxFONTWEIGHT_BOLD);
auto *box_slic3r = new wxCheckBox(this, wxID_ANY, _L("Check for application updates")); auto *box_slic3r = new wxCheckBox(this, wxID_ANY, _L("Check for application updates"));
box_slic3r->SetValue(app_config->get("version_check") == "1"); box_slic3r->SetValue(app_config->get("notify_release") != "none");
append(box_slic3r); append(box_slic3r);
append_text(wxString::Format(_L( append_text(wxString::Format(_L(
"If enabled, %s checks for new application versions online. When a new version becomes available, " "If enabled, %s checks for new application versions online. When a new version becomes available, "
@ -2697,7 +2697,7 @@ bool ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese
app_config->set_vendors(appconfig_new); app_config->set_vendors(appconfig_new);
app_config->set("version_check", page_update->version_check ? "1" : "0"); app_config->set("notify_release", page_update->version_check ? "all" : "none");
app_config->set("preset_update", page_update->preset_update ? "1" : "0"); app_config->set("preset_update", page_update->preset_update ? "1" : "0");
app_config->set("export_sources_full_pathnames", page_reload_from_disk->full_pathnames ? "1" : "0"); app_config->set("export_sources_full_pathnames", page_reload_from_disk->full_pathnames ? "1" : "0");

View File

@ -83,6 +83,9 @@
#include <wx/msw/dark_mode.h> #include <wx/msw/dark_mode.h>
#endif // _MSW_DARK_MODE #endif // _MSW_DARK_MODE
#endif #endif
#ifdef _WIN32
#include <boost/dll/runtime_symbol_info.hpp>
#endif
#if ENABLE_THUMBNAIL_GENERATOR_DEBUG #if ENABLE_THUMBNAIL_GENERATOR_DEBUG
#include <boost/beast/core/detail/base64.hpp> #include <boost/beast/core/detail/base64.hpp>
@ -424,6 +427,56 @@ bool static check_old_linux_datadir(const wxString& app_name) {
#endif #endif
#ifdef _WIN32
static bool run_updater_win()
{
// find updater exe
boost::filesystem::path path_to_binary = boost::dll::program_location();
for (const auto& dir_entry : boost::filesystem::directory_iterator(path_to_binary.parent_path())) {
if (dir_entry.path().filename() == "prusaslicer-updater.exe") {
// run updater. Original args: /silent -restartapp prusa-slicer.exe -startappfirst
// Using quoted string as mentioned in CreateProcessW docs.
std::wstring wcmd = L"\"" + dir_entry.path().wstring() + L"\"";
wcmd += L" /silent";
// additional information
STARTUPINFOW si;
PROCESS_INFORMATION pi;
// set the size of the structures
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
// start the program up
if (CreateProcessW(NULL, // the path
wcmd.data(), // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi // Pointer to PROCESS_INFORMATION structure (removed extra parentheses)
)) {
// Close process and thread handles.
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return true;
} else {
BOOST_LOG_TRIVIAL(error) << "Failed to start prusaslicer-updater.exe with command " << wcmd;
}
break;
}
}
return false;
}
#endif //_WIN32
wxString file_wildcards(FileType file_type, const std::string &custom_extension) wxString file_wildcards(FileType file_type, const std::string &custom_extension)
{ {
static const std::string defaults[FT_SIZE] = { static const std::string defaults[FT_SIZE] = {
@ -678,7 +731,6 @@ void GUI_App::post_init()
this->check_updates(false); this->check_updates(false);
CallAfter([this] { CallAfter([this] {
bool cw_showed = this->config_wizard_startup(); bool cw_showed = this->config_wizard_startup();
this->preset_updater->slic3r_update_notify();
this->preset_updater->sync(preset_bundle); this->preset_updater->sync(preset_bundle);
if (! cw_showed) { if (! cw_showed) {
// The CallAfter is needed as well, without it, GL extensions did not show. // The CallAfter is needed as well, without it, GL extensions did not show.
@ -686,6 +738,15 @@ void GUI_App::post_init()
// sees something else than "we want something" on the first start. // sees something else than "we want something" on the first start.
show_send_system_info_dialog_if_needed(); show_send_system_info_dialog_if_needed();
} }
bool updater_running =
#ifdef _WIN32
// Run external updater on Windows.
run_updater_win();
#else
false;
#endif // _WIN32
if (!updater_running)
this->preset_updater->slic3r_update_notify();
}); });
} }
@ -1070,26 +1131,30 @@ bool GUI_App::on_init_inner()
Bind(EVT_SLIC3R_VERSION_ONLINE, [this](const wxCommandEvent& evt) { Bind(EVT_SLIC3R_VERSION_ONLINE, [this](const wxCommandEvent& evt) {
app_config->set("version_online", into_u8(evt.GetString())); app_config->set("version_online", into_u8(evt.GetString()));
app_config->save(); app_config->save();
if (this->plater_ != nullptr) { std::string opt = app_config->get("notify_release");
if (this->plater_ != nullptr && (opt == "all" || opt == "release")) {
if (*Semver::parse(SLIC3R_VERSION) < *Semver::parse(into_u8(evt.GetString()))) { if (*Semver::parse(SLIC3R_VERSION) < *Semver::parse(into_u8(evt.GetString()))) {
this->plater_->get_notification_manager()->push_notification(NotificationType::NewAppAvailable); this->plater_->get_notification_manager()->push_notification(NotificationType::NewAppAvailable
, NotificationManager::NotificationLevel::ImportantNotificationLevel
, Slic3r::format(_u8L("New release version %1% is available."), evt.GetString())
, _u8L("See Download page.")
, [](wxEvtHandler* evnthndlr) {wxGetApp().open_web_page_localized("https://www.prusa3d.com/slicerweb"); return true; }
);
} }
} }
}); });
Bind(EVT_SLIC3R_ALPHA_VERSION_ONLINE, [this](const wxCommandEvent& evt) { Bind(EVT_SLIC3R_EXPERIMENTAL_VERSION_ONLINE, [this](const wxCommandEvent& evt) {
app_config->save(); app_config->save();
if (this->plater_ != nullptr && app_config->get("notify_testing_release") == "1") { if (this->plater_ != nullptr && app_config->get("notify_release") == "all") {
if (*Semver::parse(SLIC3R_VERSION) < *Semver::parse(into_u8(evt.GetString()))) { std::string evt_string = into_u8(evt.GetString());
this->plater_->get_notification_manager()->push_notification(NotificationType::NewAlphaAvailable); if (*Semver::parse(SLIC3R_VERSION) < *Semver::parse(evt_string)) {
} auto notif_type = (evt_string.find("beta") != std::string::npos ? NotificationType::NewBetaAvailable : NotificationType::NewAlphaAvailable);
} this->plater_->get_notification_manager()->push_notification( notif_type
}); , NotificationManager::NotificationLevel::ImportantNotificationLevel
Bind(EVT_SLIC3R_BETA_VERSION_ONLINE, [this](const wxCommandEvent& evt) { , Slic3r::format(_u8L("New prerelease version %1% is available."), evt_string)
app_config->save(); , _u8L("See Releases page.")
if (this->plater_ != nullptr && app_config->get("notify_testing_release") == "1") { , [](wxEvtHandler* evnthndlr) {wxGetApp().open_browser_with_warning_dialog("https://github.com/prusa3d/PrusaSlicer/releases"); return true; }
if (*Semver::parse(SLIC3R_VERSION) < *Semver::parse(into_u8(evt.GetString()))) { );
this->plater_->get_notification_manager()->close_notification_of_type(NotificationType::NewAlphaAvailable);
this->plater_->get_notification_manager()->push_notification(NotificationType::NewBetaAvailable);
} }
} }
}); });
@ -2032,7 +2097,7 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
local_menu->Append(config_id_base + ConfigMenuWizard, config_wizard_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 Configuration Updates"), _L("Check for configuration updates"));
#if defined(__linux__) && defined(SLIC3R_DESKTOP_INTEGRATION) #if defined(__linux__) && defined(SLIC3R_DESKTOP_INTEGRATION)
//if (DesktopIntegrationDialog::integration_possible()) //if (DesktopIntegrationDialog::integration_possible())
local_menu->Append(config_id_base + ConfigMenuDesktopIntegration, _L("Desktop Integration"), _L("Desktop Integration")); local_menu->Append(config_id_base + ConfigMenuDesktopIntegration, _L("Desktop Integration"), _L("Desktop Integration"));

View File

@ -101,7 +101,7 @@ GalleryDialog::GalleryDialog(wxWindow* parent, bool modify_gallery/* = false*/)
ok_btn->SetToolTip(_L("Add selected shape(s) to the bed")); ok_btn->SetToolTip(_L("Add selected shape(s) to the bed"));
} }
static_cast<wxButton*>(FindWindowById(wxID_CLOSE, this))->Bind(wxEVT_BUTTON, [this](wxCommandEvent&){ this->EndModal(wxID_CLOSE); }); static_cast<wxButton*>(FindWindowById(wxID_CLOSE, this))->Bind(wxEVT_BUTTON, [this](wxCommandEvent&){ this->EndModal(wxID_CLOSE); });
this->SetEscapeId(wxID_CLOSE);
auto add_btn = [this, buttons]( size_t pos, int& ID, wxString title, wxString tooltip, auto add_btn = [this, buttons]( size_t pos, int& ID, wxString title, wxString tooltip,
void (GalleryDialog::* method)(wxEvent&), void (GalleryDialog::* method)(wxEvent&),
std::function<bool()> enable_fn = []() {return true; }) { std::function<bool()> enable_fn = []() {return true; }) {

View File

@ -585,9 +585,21 @@ GLGizmoRotate3D::RotoptimzeWindow::RotoptimzeWindow(ImGuiWrapper * imgui,
y = std::min(y, alignment.bottom_limit - win_h); y = std::min(y, alignment.bottom_limit - win_h);
ImGui::SetWindowPos(ImVec2(x, y), ImGuiCond_Always); ImGui::SetWindowPos(ImVec2(x, y), ImGuiCond_Always);
ImGui::PushItemWidth(300.f); float max_text_w = 0.;
auto padding = ImGui::GetStyle().FramePadding;
padding.x *= 2.f;
padding.y *= 2.f;
if (ImGui::BeginCombo(_L("Choose goal").c_str(), RotoptimizeJob::get_method_name(state.method_id).c_str())) { for (size_t i = 0; i < RotoptimizeJob::get_methods_count(); ++i) {
float w =
ImGui::CalcTextSize(RotoptimizeJob::get_method_name(i).c_str()).x +
padding.x + ImGui::GetFrameHeight();
max_text_w = std::max(w, max_text_w);
}
ImGui::PushItemWidth(max_text_w);
if (ImGui::BeginCombo("", RotoptimizeJob::get_method_name(state.method_id).c_str())) {
for (size_t i = 0; i < RotoptimizeJob::get_methods_count(); ++i) { for (size_t i = 0; i < RotoptimizeJob::get_methods_count(); ++i) {
if (ImGui::Selectable(RotoptimizeJob::get_method_name(i).c_str())) { if (ImGui::Selectable(RotoptimizeJob::get_method_name(i).c_str())) {
state.method_id = i; state.method_id = i;
@ -603,12 +615,18 @@ GLGizmoRotate3D::RotoptimzeWindow::RotoptimzeWindow(ImGuiWrapper * imgui,
ImGui::EndCombo(); ImGui::EndCombo();
} }
ImVec2 sz = ImGui::GetItemRectSize();
if (ImGui::IsItemHovered()) if (ImGui::IsItemHovered())
ImGui::SetTooltip("%s", RotoptimizeJob::get_method_description(state.method_id).c_str()); ImGui::SetTooltip("%s", RotoptimizeJob::get_method_description(state.method_id).c_str());
ImGui::Separator(); ImGui::Separator();
if ( imgui->button(_L("Optimize")) ) { auto btn_txt = _L("Apply");
auto btn_txt_sz = ImGui::CalcTextSize(btn_txt.c_str());
ImVec2 button_sz = {btn_txt_sz.x + padding.x, btn_txt_sz.y + padding.y};
ImGui::SetCursorPosX(padding.x + sz.x - button_sz.x);
if ( imgui->button(btn_txt) ) {
wxGetApp().plater()->optimize_rotation(); wxGetApp().plater()->optimize_rotation();
} }
} }

View File

@ -1189,6 +1189,7 @@ void ImGuiWrapper::init_input()
io.KeyMap[ImGuiKey_Backspace] = WXK_BACK; io.KeyMap[ImGuiKey_Backspace] = WXK_BACK;
io.KeyMap[ImGuiKey_Space] = WXK_SPACE; io.KeyMap[ImGuiKey_Space] = WXK_SPACE;
io.KeyMap[ImGuiKey_Enter] = WXK_RETURN; io.KeyMap[ImGuiKey_Enter] = WXK_RETURN;
io.KeyMap[ImGuiKey_KeyPadEnter] = WXK_NUMPAD_ENTER;
io.KeyMap[ImGuiKey_Escape] = WXK_ESCAPE; io.KeyMap[ImGuiKey_Escape] = WXK_ESCAPE;
io.KeyMap[ImGuiKey_A] = 'A'; io.KeyMap[ImGuiKey_A] = 'A';
io.KeyMap[ImGuiKey_C] = 'C'; io.KeyMap[ImGuiKey_C] = 'C';

View File

@ -6,6 +6,8 @@
#include <imgui/imgui.h> #include <imgui/imgui.h>
#include <wx/string.h>
#include "libslic3r/Point.hpp" #include "libslic3r/Point.hpp"
namespace Slic3r {namespace Search { namespace Slic3r {namespace Search {

View File

@ -63,9 +63,9 @@ MsgDialog::MsgDialog(wxWindow *parent, const wxString &title, const wxString &he
SetSizerAndFit(main_sizer); SetSizerAndFit(main_sizer);
} }
void MsgDialog::add_btn(wxWindowID btn_id, bool set_focus /*= false*/) void MsgDialog::add_btn(wxWindowID btn_id, bool set_focus /*= false*/, const wxString& label/* = wxString()*/)
{ {
wxButton* btn = new wxButton(this, btn_id); wxButton* btn = new wxButton(this, btn_id, label);
if (set_focus) if (set_focus)
btn->SetFocus(); btn->SetFocus();
btn_sizer->Add(btn, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, HORIZ_SPACING); btn_sizer->Add(btn, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, HORIZ_SPACING);
@ -75,7 +75,7 @@ void MsgDialog::add_btn(wxWindowID btn_id, bool set_focus /*= false*/)
void MsgDialog::apply_style(long style) void MsgDialog::apply_style(long style)
{ {
if (style & wxOK) add_btn(wxID_OK, true); if (style & wxOK) add_btn(wxID_OK, true);
if (style & wxYES) add_btn(wxID_YES); if (style & wxYES) add_btn(wxID_YES, true);
if (style & wxNO) add_btn(wxID_NO); if (style & wxNO) add_btn(wxID_NO);
if (style & wxCANCEL) add_btn(wxID_CANCEL); if (style & wxCANCEL) add_btn(wxID_CANCEL);
@ -118,7 +118,7 @@ static void add_msg_content(wxWindow* parent, wxBoxSizer* content_sizer, wxStrin
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
wxFont monospace = wxGetApp().code_font(); wxFont monospace = wxGetApp().code_font();
wxColour text_clr = wxGetApp().get_label_clr_default(); wxColour text_clr = wxGetApp().get_label_clr_default();
wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); wxColour bgr_clr = parent->GetBackgroundColour(); //wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue()); auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue());
auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue()); auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue());
const int font_size = font.GetPointSize(); const int font_size = font.GetPointSize();

View File

@ -43,7 +43,7 @@ protected:
MsgDialog(wxWindow *parent, const wxString &title, const wxString &headline, long style = wxOK, wxBitmap bitmap = wxNullBitmap); MsgDialog(wxWindow *parent, const wxString &title, const wxString &headline, long style = wxOK, wxBitmap bitmap = wxNullBitmap);
void add_btn(wxWindowID btn_id, bool set_focus = false); void add_btn(wxWindowID btn_id, bool set_focus = false, const wxString& label = wxString());
void apply_style(long style); void apply_style(long style);
void finalize(); void finalize();

View File

@ -41,12 +41,6 @@ const NotificationManager::NotificationData NotificationManager::basic_notificat
return true; return true;
} }
}, },
{NotificationType::NewAppAvailable, NotificationLevel::ImportantNotificationLevel, 20, _u8L("New version is available."), _u8L("See Releases page."), [](wxEvtHandler* evnthndlr) {
wxGetApp().open_browser_with_warning_dialog("https://github.com/prusa3d/PrusaSlicer/releases"); return true; }},
{NotificationType::NewAlphaAvailable, NotificationLevel::ImportantNotificationLevel, 20, _u8L("New alpha release is available."), _u8L("See Releases page."), [](wxEvtHandler* evnthndlr) {
wxGetApp().open_browser_with_warning_dialog("https://github.com/prusa3d/PrusaSlicer/releases"); return true; }},
{NotificationType::NewBetaAvailable, NotificationLevel::ImportantNotificationLevel, 20, _u8L("New beta release is available."), _u8L("See Releases page."), [](wxEvtHandler* evnthndlr) {
wxGetApp().open_browser_with_warning_dialog("https://github.com/prusa3d/PrusaSlicer/releases"); return true; }},
{NotificationType::EmptyColorChangeCode, NotificationLevel::PrintInfoNotificationLevel, 10, {NotificationType::EmptyColorChangeCode, NotificationLevel::PrintInfoNotificationLevel, 10,
_u8L("You have just added a G-code for color change, but its value is empty.\n" _u8L("You have just added a G-code for color change, but its value is empty.\n"
"To export the G-code correctly, check the \"Color Change G-code\" in \"Printer Settings > Custom G-code\"") }, "To export the G-code correctly, check the \"Color Change G-code\" in \"Printer Settings > Custom G-code\"") },
@ -61,6 +55,8 @@ const NotificationManager::NotificationData NotificationManager::basic_notificat
{NotificationType::UndoDesktopIntegrationFail, NotificationLevel::WarningNotificationLevel, 10, {NotificationType::UndoDesktopIntegrationFail, NotificationLevel::WarningNotificationLevel, 10,
_u8L("Undo desktop integration failed.") }, _u8L("Undo desktop integration failed.") },
{NotificationType::ExportOngoing, NotificationLevel::RegularNotificationLevel, 0, _u8L("Exporting.") }, {NotificationType::ExportOngoing, NotificationLevel::RegularNotificationLevel, 0, _u8L("Exporting.") },
//{NotificationType::NewAppAvailable, NotificationLevel::ImportantNotificationLevel, 20, _u8L("New version is available."), _u8L("See Releases page."), [](wxEvtHandler* evnthndlr) {
// wxGetApp().open_browser_with_warning_dialog("https://github.com/prusa3d/PrusaSlicer/releases"); return true; }},
//{NotificationType::NewAppAvailable, NotificationLevel::ImportantNotificationLevel, 20, _u8L("New vesion of PrusaSlicer is available.", _u8L("Download page.") }, //{NotificationType::NewAppAvailable, NotificationLevel::ImportantNotificationLevel, 20, _u8L("New vesion of PrusaSlicer is available.", _u8L("Download page.") },
//{NotificationType::LoadingFailed, NotificationLevel::RegularNotificationLevel, 20, _u8L("Loading of model has Failed") }, //{NotificationType::LoadingFailed, NotificationLevel::RegularNotificationLevel, 20, _u8L("Loading of model has Failed") },
//{NotificationType::DeviceEjected, NotificationLevel::RegularNotificationLevel, 10, _u8L("Removable device has been safely ejected")} // if we want changeble text (like here name of device), we need to do it as CustomNotification //{NotificationType::DeviceEjected, NotificationLevel::RegularNotificationLevel, 10, _u8L("Removable device has been safely ejected")} // if we want changeble text (like here name of device), we need to do it as CustomNotification

View File

@ -150,7 +150,7 @@ public:
// Push a NotificationType::CustomNotification with NotificationLevel::RegularNotificationLevel and 10s fade out interval. // Push a NotificationType::CustomNotification with NotificationLevel::RegularNotificationLevel and 10s fade out interval.
void push_notification(const std::string& text, int timestamp = 0); void push_notification(const std::string& text, int timestamp = 0);
// Push a NotificationType::CustomNotification with provided notification level and 10s for RegularNotificationLevel. // Push a NotificationType::CustomNotification with provided notification level and 10s for RegularNotificationLevel.
// ErrorNotificationLevel and ImportantNotificationLevel are never faded out. // ErrorNotificationLevel are never faded out.
void push_notification(NotificationType type, NotificationLevel level, const std::string& text, const std::string& hypertext = "", void push_notification(NotificationType type, NotificationLevel level, const std::string& text, const std::string& hypertext = "",
std::function<bool(wxEvtHandler*)> callback = std::function<bool(wxEvtHandler*)>(), int timestamp = 0); std::function<bool(wxEvtHandler*)> callback = std::function<bool(wxEvtHandler*)>(), int timestamp = 0);
// Pushes basic_notification with delay. See push_delayed_notification_data. // Pushes basic_notification with delay. See push_delayed_notification_data.
@ -720,7 +720,7 @@ private:
case NotificationLevel::ErrorNotificationLevel: return 0; case NotificationLevel::ErrorNotificationLevel: return 0;
case NotificationLevel::WarningNotificationLevel: return 0; case NotificationLevel::WarningNotificationLevel: return 0;
case NotificationLevel::ImportantNotificationLevel: return 0; case NotificationLevel::ImportantNotificationLevel: return 20;
case NotificationLevel::ProgressBarNotificationLevel: return 2; case NotificationLevel::ProgressBarNotificationLevel: return 2;
case NotificationLevel::PrintInfoShortNotificationLevel: return 5; case NotificationLevel::PrintInfoShortNotificationLevel: return 5;
case NotificationLevel::RegularNotificationLevel: return 10; case NotificationLevel::RegularNotificationLevel: return 10;

View File

@ -534,7 +534,7 @@ void PhysicalPrinterDialog::update_host_type(bool printer_change)
[model_id](const VendorProfile::PrinterModel& model) { return model.id == model_id; }); [model_id](const VendorProfile::PrinterModel& model) { return model.id == model_id; });
if (it != models.end() && (it->family == "MK3" || it->family == "MINI")) if (it != models.end() && (it->family == "MK3" || it->family == "MINI"))
continue; continue;
} else if (!preset->vendor && (boost::ends_with(model_id, "MK3") || boost::ends_with(model_id, "MINI"))) { } else if (!preset->vendor && (boost::starts_with(model_id, "MK3") || boost::starts_with(model_id, "MINI"))) {
continue; continue;
} }

View File

@ -5071,6 +5071,7 @@ void Plater::new_project()
Plater::SuppressSnapshots suppress(this); Plater::SuppressSnapshots suppress(this);
reset(); reset();
reset_project_dirty_initial_presets(); reset_project_dirty_initial_presets();
wxGetApp().update_saved_preset_from_current_preset();
update_project_dirty_from_presets(); update_project_dirty_from_presets();
} }

View File

@ -141,14 +141,6 @@ void PreferencesDialog::build(size_t selected_tab)
option = Option(def, "background_processing"); option = Option(def, "background_processing");
m_optgroup_general->append_single_option_line(option); m_optgroup_general->append_single_option_line(option);
// Please keep in sync with ConfigWizard
def.label = L("Check for application updates");
def.type = coBool;
def.tooltip = L("If enabled, PrusaSlicer will check for the new versions of itself online. When a new version becomes available a notification is displayed at the next application startup (never during program usage). This is only a notification mechanisms, no automatic installation is done.");
def.set_default_value(new ConfigOptionBool(app_config->get("version_check") == "1"));
option = Option(def, "version_check");
m_optgroup_general->append_single_option_line(option);
m_optgroup_general->append_separator(); m_optgroup_general->append_separator();
// Please keep in sync with ConfigWizard // Please keep in sync with ConfigWizard

View File

@ -39,7 +39,7 @@ static const char *CONFIG_KEY_PRINT = "printhost_print";
static const char *CONFIG_KEY_GROUP = "printhost_group"; static const char *CONFIG_KEY_GROUP = "printhost_group";
PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, bool can_start_print, const wxArrayString &groups) PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, bool can_start_print, const wxArrayString &groups)
: MsgDialog(static_cast<wxWindow*>(wxGetApp().mainframe), _L("Send G-Code to printer host"), _L("Upload to Printer Host with the following filename:"), wxID_NONE) : MsgDialog(static_cast<wxWindow*>(wxGetApp().mainframe), _L("Send G-Code to printer host"), _L("Upload to Printer Host with the following filename:"), wxOK | wxCANCEL)
, txt_filename(new wxTextCtrl(this, wxID_ANY)) , txt_filename(new wxTextCtrl(this, wxID_ANY))
, box_print(can_start_print ? new wxCheckBox(this, wxID_ANY, _L("Start printing after upload")) : nullptr) , box_print(can_start_print ? new wxCheckBox(this, wxID_ANY, _L("Start printing after upload")) : nullptr)
, combo_groups(!groups.IsEmpty() ? new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, groups, wxCB_READONLY) : nullptr) , combo_groups(!groups.IsEmpty() ? new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, groups, wxCB_READONLY) : nullptr)
@ -70,10 +70,6 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, bool can_start_pr
combo_groups->SetValue(recent_group); combo_groups->SetValue(recent_group);
} }
auto* szr = CreateStdDialogButtonSizer(wxOK | wxCANCEL);
auto* btn_ok = szr->GetAffirmativeButton();
btn_sizer->Add(szr);
wxString recent_path = from_u8(app_config->get("recent", CONFIG_KEY_PATH)); wxString recent_path = from_u8(app_config->get("recent", CONFIG_KEY_PATH));
if (recent_path.Length() > 0 && recent_path[recent_path.Length() - 1] != '/') { if (recent_path.Length() > 0 && recent_path[recent_path.Length() - 1] != '/') {
recent_path += '/'; recent_path += '/';
@ -88,23 +84,19 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, bool can_start_pr
wxString suffix = recent_path.substr(recent_path.find_last_of('.')); wxString suffix = recent_path.substr(recent_path.find_last_of('.'));
btn_ok->Bind(wxEVT_BUTTON, [this, suffix](wxCommandEvent&) { static_cast<wxButton*>(FindWindowById(wxID_OK, this))->Bind(wxEVT_BUTTON, [this, suffix](wxCommandEvent&) {
wxString path = txt_filename->GetValue(); wxString path = txt_filename->GetValue();
// .gcode suffix control // .gcode suffix control
if (!path.Lower().EndsWith(suffix.Lower())) if (!path.Lower().EndsWith(suffix.Lower()))
{ {
//wxMessageDialog msg_wingow(this, wxString::Format(_L("Upload filename doesn't end with \"%s\". Do you wish to continue?"), suffix), wxString(SLIC3R_APP_NAME), wxYES | wxNO);
MessageDialog msg_wingow(this, wxString::Format(_L("Upload filename doesn't end with \"%s\". Do you wish to continue?"), suffix), wxString(SLIC3R_APP_NAME), wxYES | wxNO); MessageDialog msg_wingow(this, wxString::Format(_L("Upload filename doesn't end with \"%s\". Do you wish to continue?"), suffix), wxString(SLIC3R_APP_NAME), wxYES | wxNO);
if (msg_wingow.ShowModal() == wxID_NO) if (msg_wingow.ShowModal() == wxID_NO)
return; return;
} }
EndDialog(wxID_OK); EndDialog(wxID_OK);
}); });
wxGetApp().UpdateDlgDarkUI(this); finalize();
Fit();
CenterOnParent();
#ifdef __linux__ #ifdef __linux__
// On Linux with GTK2 when text control lose the focus then selection (colored background) disappears but text color stay white // On Linux with GTK2 when text control lose the focus then selection (colored background) disappears but text color stay white

View File

@ -26,7 +26,7 @@ namespace GUI {
static const char* URL_CHANGELOG = "https://files.prusa3d.com/?latest=slicer-stable&lng=%1%"; static const char* URL_CHANGELOG = "https://files.prusa3d.com/?latest=slicer-stable&lng=%1%";
static const char* URL_DOWNLOAD = "https://www.prusa3d.com/downloads&lng=%1%"; static const char* URL_DOWNLOAD = "https://www.prusa3d.com/slicerweb&lng=%1%";
static const char* URL_DEV = "https://github.com/prusa3d/PrusaSlicer/releases/tag/version_%1%"; static const char* URL_DEV = "https://github.com/prusa3d/PrusaSlicer/releases/tag/version_%1%";
static const std::string CONFIG_UPDATE_WIKI_URL("https://github.com/prusa3d/PrusaSlicer/wiki/Slic3r-PE-1.40-configuration-update"); static const std::string CONFIG_UPDATE_WIKI_URL("https://github.com/prusa3d/PrusaSlicer/wiki/Slic3r-PE-1.40-configuration-update");
@ -89,7 +89,7 @@ MsgUpdateConfig::MsgUpdateConfig(const std::vector<Update> &updates, bool force_
MsgDialog(nullptr, force_before_wizard ? _L("Opening Configuration Wizard") : _L("Configuration update"), MsgDialog(nullptr, force_before_wizard ? _L("Opening Configuration Wizard") : _L("Configuration update"),
force_before_wizard ? _L("PrusaSlicer is not using the newest configuration available.\n" force_before_wizard ? _L("PrusaSlicer is not using the newest configuration available.\n"
"Configuration Wizard may not offer the latest printers, filaments and SLA materials to be installed. ") : "Configuration Wizard may not offer the latest printers, filaments and SLA materials to be installed. ") :
_L("Configuration update is available"), wxID_NONE) _L("Configuration update is available"), wxICON_ERROR)
{ {
auto *text = new wxStaticText(this, wxID_ANY, _(L( auto *text = new wxStaticText(this, wxID_ANY, _(L(
"Would you like to install it?\n\n" "Would you like to install it?\n\n"
@ -133,22 +133,14 @@ MsgUpdateConfig::MsgUpdateConfig(const std::vector<Update> &updates, bool force_
content_sizer->Add(versions); content_sizer->Add(versions);
content_sizer->AddSpacer(2*VERT_SPACING); content_sizer->AddSpacer(2*VERT_SPACING);
auto* btn_ok = new wxButton(this, wxID_OK, force_before_wizard ? _L("Install") : "OK"); add_btn(wxID_OK, true, force_before_wizard ? _L("Install") : "OK");
btn_sizer->Add(btn_ok);
btn_sizer->AddSpacer(HORIZ_SPACING);
if (force_before_wizard) { if (force_before_wizard) {
auto* btn_no_install = new wxButton(this, wxID_ANY, "Don't install"); add_btn(wxID_CLOSE, false, _L("Don't install"));
btn_no_install->Bind(wxEVT_BUTTON, [this](wxEvent&) { this->EndModal(wxID_CLOSE); }); static_cast<wxButton*>(FindWindowById(wxID_CLOSE, this))->Bind(wxEVT_BUTTON, [this](const wxCommandEvent&) { this->EndModal(wxID_CLOSE); });
btn_sizer->Add(btn_no_install);
btn_sizer->AddSpacer(HORIZ_SPACING);
} }
auto* btn_cancel = new wxButton(this, wxID_CANCEL); add_btn(wxID_CANCEL);
btn_sizer->Add(btn_cancel);
btn_ok->SetFocus();
wxGetApp().UpdateDlgDarkUI(this); finalize();
Fit();
} }
MsgUpdateConfig::~MsgUpdateConfig() {} MsgUpdateConfig::~MsgUpdateConfig() {}
@ -156,7 +148,7 @@ MsgUpdateConfig::~MsgUpdateConfig() {}
//MsgUpdateForced //MsgUpdateForced
MsgUpdateForced::MsgUpdateForced(const std::vector<Update>& updates) : MsgUpdateForced::MsgUpdateForced(const std::vector<Update>& updates) :
MsgDialog(nullptr, wxString::Format(_(L("%s incompatibility")), SLIC3R_APP_NAME), _(L("You must install a configuration update.")) + " ", wxICON_ERROR) MsgDialog(nullptr, wxString::Format(_(L("%s incompatibility")), SLIC3R_APP_NAME), _(L("You must install a configuration update.")) + " ", wxOK | wxICON_ERROR)
{ {
auto* text = new wxStaticText(this, wxID_ANY, wxString::Format(_(L( auto* text = new wxStaticText(this, wxID_ANY, wxString::Format(_(L(
"%s will now start updates. Otherwise it won't be able to start.\n\n" "%s will now start updates. Otherwise it won't be able to start.\n\n"
@ -197,17 +189,10 @@ MsgUpdateForced::MsgUpdateForced(const std::vector<Update>& updates) :
content_sizer->Add(versions); content_sizer->Add(versions);
content_sizer->AddSpacer(2 * VERT_SPACING); content_sizer->AddSpacer(2 * VERT_SPACING);
auto* btn_exit = new wxButton(this, wxID_EXIT, wxString::Format(_(L("Exit %s")), SLIC3R_APP_NAME));
btn_sizer->Add(btn_exit);
btn_sizer->AddSpacer(HORIZ_SPACING);
auto* btn_ok = new wxButton(this, wxID_OK);
btn_sizer->Add(btn_ok);
btn_ok->SetFocus();
auto exiter = [this](const wxCommandEvent& evt) { this->EndModal(evt.GetId()); }; add_btn(wxID_EXIT, false, wxString::Format(_L("Exit %s"), SLIC3R_APP_NAME));
btn_exit->Bind(wxEVT_BUTTON, exiter); for (auto ID : { wxID_EXIT, wxID_OK })
btn_ok->Bind(wxEVT_BUTTON, exiter); static_cast<wxButton*>(FindWindowById(ID, this))->Bind(wxEVT_BUTTON, [this](const wxCommandEvent& evt) { this->EndModal(evt.GetId()); });
finalize(); finalize();
} }
@ -218,7 +203,7 @@ MsgUpdateForced::~MsgUpdateForced() {}
MsgDataIncompatible::MsgDataIncompatible(const std::unordered_map<std::string, wxString> &incompats) : MsgDataIncompatible::MsgDataIncompatible(const std::unordered_map<std::string, wxString> &incompats) :
MsgDialog(nullptr, wxString::Format(_(L("%s incompatibility")), SLIC3R_APP_NAME), MsgDialog(nullptr, wxString::Format(_(L("%s incompatibility")), SLIC3R_APP_NAME),
wxString::Format(_(L("%s configuration is incompatible")), SLIC3R_APP_NAME), /*wxID_NONE | */wxICON_ERROR) wxString::Format(_(L("%s configuration is incompatible")), SLIC3R_APP_NAME), wxICON_ERROR)
{ {
auto *text = new wxStaticText(this, wxID_ANY, wxString::Format(_(L( auto *text = new wxStaticText(this, wxID_ANY, wxString::Format(_(L(
"This version of %s is not compatible with currently installed configuration bundles.\n" "This version of %s is not compatible with currently installed configuration bundles.\n"
@ -251,16 +236,11 @@ MsgDataIncompatible::MsgDataIncompatible(const std::unordered_map<std::string, w
content_sizer->Add(versions); content_sizer->Add(versions);
content_sizer->AddSpacer(2*VERT_SPACING); content_sizer->AddSpacer(2*VERT_SPACING);
auto *btn_exit = new wxButton(this, wxID_EXIT, wxString::Format(_(L("Exit %s")), SLIC3R_APP_NAME)); add_btn(wxID_REPLACE, true, _L("Re-configure"));
btn_sizer->Add(btn_exit); add_btn(wxID_EXIT, false, wxString::Format(_L("Exit %s"), SLIC3R_APP_NAME));
btn_sizer->AddSpacer(HORIZ_SPACING);
auto *btn_reconf = new wxButton(this, wxID_REPLACE, _(L("Re-configure")));
btn_sizer->Add(btn_reconf);
btn_exit->SetFocus();
auto exiter = [this](const wxCommandEvent& evt) { this->EndModal(evt.GetId()); }; for (auto ID : {wxID_EXIT, wxID_REPLACE})
btn_exit->Bind(wxEVT_BUTTON, exiter); static_cast<wxButton*>(FindWindowById(ID, this))->Bind(wxEVT_BUTTON, [this](const wxCommandEvent& evt) { this->EndModal(evt.GetId()); });
btn_reconf->Bind(wxEVT_BUTTON, exiter);
finalize(); finalize();
} }
@ -309,7 +289,7 @@ MsgDataLegacy::~MsgDataLegacy() {}
// MsgNoUpdate // MsgNoUpdate
MsgNoUpdates::MsgNoUpdates() : MsgNoUpdates::MsgNoUpdates() :
MsgDialog(nullptr, _(L("Configuration updates")), _(L("No updates available")), wxICON_ERROR) MsgDialog(nullptr, _(L("Configuration updates")), _(L("No updates available")), wxICON_ERROR | wxOK)
{ {
auto* text = new wxStaticText(this, wxID_ANY, wxString::Format( auto* text = new wxStaticText(this, wxID_ANY, wxString::Format(

View File

@ -137,8 +137,7 @@ struct Updates
wxDEFINE_EVENT(EVT_SLIC3R_VERSION_ONLINE, wxCommandEvent); wxDEFINE_EVENT(EVT_SLIC3R_VERSION_ONLINE, wxCommandEvent);
wxDEFINE_EVENT(EVT_SLIC3R_ALPHA_VERSION_ONLINE, wxCommandEvent); wxDEFINE_EVENT(EVT_SLIC3R_EXPERIMENTAL_VERSION_ONLINE, wxCommandEvent);
wxDEFINE_EVENT(EVT_SLIC3R_BETA_VERSION_ONLINE, wxCommandEvent);
struct PresetUpdater::priv struct PresetUpdater::priv
{ {
@ -189,7 +188,7 @@ PresetUpdater::priv::priv()
// Pull relevant preferences from AppConfig // Pull relevant preferences from AppConfig
void PresetUpdater::priv::set_download_prefs(AppConfig *app_config) void PresetUpdater::priv::set_download_prefs(AppConfig *app_config)
{ {
enabled_version_check = app_config->get("version_check") == "1"; enabled_version_check = app_config->get("notify_release") != "none";
version_check_url = app_config->version_check_url(); version_check_url = app_config->version_check_url();
enabled_config_update = app_config->get("preset_update") == "1" && !app_config->legacy_datadir(); enabled_config_update = app_config->get("preset_update") == "1" && !app_config->legacy_datadir();
} }
@ -276,8 +275,9 @@ void PresetUpdater::priv::parse_version_string(const std::string& body) const
version = body.substr(0, first_nl_pos); version = body.substr(0, first_nl_pos);
else else
version = body; version = body;
if (!Semver::parse(version)) { boost::optional<Semver> release_version = Semver::parse(version);
BOOST_LOG_TRIVIAL(warning) << format("Received invalid contents from `%1%`: Not a correct semver: `%2%`", SLIC3R_APP_NAME, version); if (!release_version) {
BOOST_LOG_TRIVIAL(error) << format("Received invalid contents from `%1%`: Not a correct semver: `%2%`", SLIC3R_APP_NAME, version);
return; return;
} }
BOOST_LOG_TRIVIAL(info) << format("Got %1% online version: `%2%`. Sending to GUI thread...", SLIC3R_APP_NAME, version); BOOST_LOG_TRIVIAL(info) << format("Got %1% online version: `%2%`. Sending to GUI thread...", SLIC3R_APP_NAME, version);
@ -286,6 +286,7 @@ void PresetUpdater::priv::parse_version_string(const std::string& body) const
GUI::wxGetApp().QueueEvent(evt); GUI::wxGetApp().QueueEvent(evt);
// alpha / beta version // alpha / beta version
std::vector<std::string> prerelease_versions;
size_t nexn_nl_pos = first_nl_pos; size_t nexn_nl_pos = first_nl_pos;
while (nexn_nl_pos != std::string::npos && body.size() > nexn_nl_pos + 1) { while (nexn_nl_pos != std::string::npos && body.size() > nexn_nl_pos + 1) {
const auto last_nl_pos = nexn_nl_pos; const auto last_nl_pos = nexn_nl_pos;
@ -300,28 +301,36 @@ void PresetUpdater::priv::parse_version_string(const std::string& body) const
if (line.substr(0, 6) == "alpha=") { if (line.substr(0, 6) == "alpha=") {
version = line.substr(6); version = line.substr(6);
if (!Semver::parse(version)) { if (!Semver::parse(version)) {
BOOST_LOG_TRIVIAL(warning) << format("Received invalid contents for alpha release from `%1%`: Not a correct semver: `%2%`", SLIC3R_APP_NAME, version); BOOST_LOG_TRIVIAL(error) << format("Received invalid contents for alpha release from `%1%`: Not a correct semver: `%2%`", SLIC3R_APP_NAME, version);
return; return;
} }
BOOST_LOG_TRIVIAL(info) << format("Got %1% online version of alpha release: `%2%`. Sending to GUI thread...", SLIC3R_APP_NAME, version); prerelease_versions.emplace_back(version);
wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_ALPHA_VERSION_ONLINE);
evt->SetString(GUI::from_u8(version));
GUI::wxGetApp().QueueEvent(evt);
// beta // beta
} }
else if (line.substr(0, 5) == "beta=") { else if (line.substr(0, 5) == "beta=") {
version = line.substr(5); version = line.substr(5);
if (!Semver::parse(version)) { if (!Semver::parse(version)) {
BOOST_LOG_TRIVIAL(warning) << format("Received invalid contents for beta release from `%1%`: Not a correct semver: `%2%`", SLIC3R_APP_NAME, version); BOOST_LOG_TRIVIAL(error) << format("Received invalid contents for beta release from `%1%`: Not a correct semver: `%2%`", SLIC3R_APP_NAME, version);
return; return;
} }
BOOST_LOG_TRIVIAL(info) << format("Got %1% online version of beta release: `%2%`. Sending to GUI thread...", SLIC3R_APP_NAME, version); prerelease_versions.emplace_back(version);
wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_BETA_VERSION_ONLINE);
evt->SetString(GUI::from_u8(version));
GUI::wxGetApp().QueueEvent(evt);
} }
} }
// find recent version that is newer than last full release.
boost::optional<Semver> recent_version;
for (const std::string& ver_string : prerelease_versions) {
boost::optional<Semver> ver = Semver::parse(ver_string);
if (ver && *release_version < *ver && ((recent_version && *recent_version < *ver) || !recent_version)) {
recent_version = ver;
version = ver_string;
}
}
if (recent_version) {
BOOST_LOG_TRIVIAL(info) << format("Got %1% online version: `%2%`. Sending to GUI thread...", SLIC3R_APP_NAME, version);
wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_EXPERIMENTAL_VERSION_ONLINE);
evt->SetString(GUI::from_u8(version));
GUI::wxGetApp().QueueEvent(evt);
}
} }
// Download vendor indices. Also download new bundles if an index indicates there's a new one available. // Download vendor indices. Also download new bundles if an index indicates there's a new one available.
@ -741,8 +750,8 @@ void PresetUpdater::sync(PresetBundle *preset_bundle)
void PresetUpdater::slic3r_update_notify() void PresetUpdater::slic3r_update_notify()
{ {
if (! p->enabled_version_check) { return; } if (! p->enabled_version_check)
return;
auto* app_config = GUI::wxGetApp().app_config; auto* app_config = GUI::wxGetApp().app_config;
const auto ver_online_str = app_config->get("version_online"); const auto ver_online_str = app_config->get("version_online");
const auto ver_online = Semver::parse(ver_online_str); const auto ver_online = Semver::parse(ver_online_str);
@ -754,7 +763,7 @@ void PresetUpdater::slic3r_update_notify()
GUI::MsgUpdateSlic3r notification(Slic3r::SEMVER, *ver_online); GUI::MsgUpdateSlic3r notification(Slic3r::SEMVER, *ver_online);
notification.ShowModal(); notification.ShowModal();
if (notification.disable_version_check()) { if (notification.disable_version_check()) {
app_config->set("version_check", "0"); app_config->set("notify_release", "none");
p->enabled_version_check = false; p->enabled_version_check = false;
} }
} }

View File

@ -63,7 +63,6 @@ private:
}; };
wxDECLARE_EVENT(EVT_SLIC3R_VERSION_ONLINE, wxCommandEvent); wxDECLARE_EVENT(EVT_SLIC3R_VERSION_ONLINE, wxCommandEvent);
wxDECLARE_EVENT(EVT_SLIC3R_ALPHA_VERSION_ONLINE, wxCommandEvent); wxDECLARE_EVENT(EVT_SLIC3R_EXPERIMENTAL_VERSION_ONLINE, wxCommandEvent);
wxDECLARE_EVENT(EVT_SLIC3R_BETA_VERSION_ONLINE, wxCommandEvent);
} }
#endif #endif