From 9994e0bcbc14fdfbd46f57d3b04d5aad087f8c36 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 1 Nov 2021 12:18:17 +0100 Subject: [PATCH 1/4] Start updater during start of prusaslicer. --- src/PrusaSlicer.cpp | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp index 41d5231f1..17a59d04a 100644 --- a/src/PrusaSlicer.cpp +++ b/src/PrusaSlicer.cpp @@ -677,6 +677,45 @@ bool CLI::setup(int argc, char **argv) set_local_dir((path_resources / "localization").string()); set_sys_shapes_dir((path_resources / "shapes").string()); +#ifdef _WIN32 + // find updater exe + for (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 + std::string args = dir_entry.path().string(); + args += " /silent"; + + // additional information + STARTUPINFOA 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 + CreateProcessA(NULL, // the path + const_cast(args.c_str()), // 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); + + break; + } + } +#endif //_WIN32 + + // Parse all command line options into a DynamicConfig. // If any option is unsupported, print usage and abort immediately. t_config_option_keys opt_order; From 262304c777f4905fc74b9c4b5d1d9819d645d54d Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 3 Nov 2021 10:57:45 +0100 Subject: [PATCH 2/4] Use correct encoding when calling external updater --- src/PrusaSlicer.cpp | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp index 17a59d04a..2b4209576 100644 --- a/src/PrusaSlicer.cpp +++ b/src/PrusaSlicer.cpp @@ -679,14 +679,18 @@ bool CLI::setup(int argc, char **argv) #ifdef _WIN32 // find updater exe - for (auto& dir_entry : boost::filesystem::directory_iterator(path_to_binary.parent_path())) { + 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 - std::string args = dir_entry.path().string(); - args += " /silent"; + + // Using quoted string as mentioned in CreateProcessW docs. + std::wstring wcmd = L"\"" + dir_entry.path().wstring() + L"\""; + wcmd += L" /silent"; + + // additional information - STARTUPINFOA si; + STARTUPINFOW si; PROCESS_INFORMATION pi; // set the size of the structures @@ -695,8 +699,8 @@ bool CLI::setup(int argc, char **argv) ZeroMemory(&pi, sizeof(pi)); // start the program up - CreateProcessA(NULL, // the path - const_cast(args.c_str()), // Command line + 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 @@ -705,11 +709,11 @@ bool CLI::setup(int argc, char **argv) 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); - + )) { + // Close process and thread handles. + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + } break; } } From 6895e0fde132f672d4a5981faff0f16b373597b3 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 3 Nov 2021 11:00:20 +0100 Subject: [PATCH 3/4] External updater is only run in GUI mode --- src/PrusaSlicer.cpp | 43 ------------------------------ src/slic3r/GUI/GUI_App.cpp | 54 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 43 deletions(-) diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp index 2b4209576..41d5231f1 100644 --- a/src/PrusaSlicer.cpp +++ b/src/PrusaSlicer.cpp @@ -677,49 +677,6 @@ bool CLI::setup(int argc, char **argv) set_local_dir((path_resources / "localization").string()); set_sys_shapes_dir((path_resources / "shapes").string()); -#ifdef _WIN32 - // find updater exe - 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); - } - break; - } - } -#endif //_WIN32 - - // Parse all command line options into a DynamicConfig. // If any option is unsupported, print usage and abort immediately. t_config_option_keys opt_order; diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 9e92f1ac9..aae61e8b5 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -83,6 +83,9 @@ #include #endif // _MSW_DARK_MODE #endif +#ifdef _WIN32 +#include +#endif #if ENABLE_THUMBNAIL_GENERATOR_DEBUG #include @@ -424,6 +427,53 @@ bool static check_old_linux_datadir(const wxString& app_name) { #endif +#ifdef _WIN32 +static void 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); + } + break; + } + } + return; +} +#endif //_WIN32 + + + wxString file_wildcards(FileType file_type, const std::string &custom_extension) { static const std::string defaults[FT_SIZE] = { @@ -686,6 +736,10 @@ void GUI_App::post_init() // sees something else than "we want something" on the first start. show_send_system_info_dialog_if_needed(); } + #ifdef _WIN32 + // Run external updater on Windows. + run_updater_win(); + #endif // _WIN32 }); } From 43986c289660f04f3698ddd082b28a1d37f3eb4e Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 8 Nov 2021 17:20:39 +0100 Subject: [PATCH 4/4] Changes in notifying about new releases. - Unified preferences settings. version_check option is replaced with notify_release that has 3 states. - fixed logic when show notification based on version string. - notification shows released version - dialog notifying new version is never showing if external updater is running. Escape quotes inside path to external updater --- src/libslic3r/AppConfig.cpp | 2 -- src/slic3r/GUI/ConfigWizard.cpp | 4 +-- src/slic3r/GUI/GUI_App.cpp | 47 ++++++++++++++++---------- src/slic3r/GUI/NotificationManager.cpp | 8 ++--- src/slic3r/GUI/NotificationManager.hpp | 4 +-- src/slic3r/GUI/Preferences.cpp | 8 ----- src/slic3r/GUI/UpdateDialogs.cpp | 2 +- src/slic3r/Utils/PresetUpdater.cpp | 47 +++++++++++++++----------- src/slic3r/Utils/PresetUpdater.hpp | 3 +- 9 files changed, 65 insertions(+), 60 deletions(-) diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index b6406bf41..9c9e7e0f3 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -71,8 +71,6 @@ void AppConfig::set_defaults() if (get("drop_project_action").empty()) set("drop_project_action", "1"); - if (get("version_check").empty()) - set("version_check", "1"); if (get("preset_update").empty()) set("preset_update", "1"); diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index 762de2cf5..737c14317 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -1206,7 +1206,7 @@ PageUpdate::PageUpdate(ConfigWizard *parent) boldfont.SetWeight(wxFONTWEIGHT_BOLD); 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_text(wxString::Format(_L( "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("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("export_sources_full_pathnames", page_reload_from_disk->full_pathnames ? "1" : "0"); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index aae61e8b5..c7513bb8b 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -428,7 +428,7 @@ bool static check_old_linux_datadir(const wxString& app_name) { #ifdef _WIN32 -static void run_updater_win() +static bool run_updater_win() { // find updater exe boost::filesystem::path path_to_binary = boost::dll::program_location(); @@ -464,11 +464,14 @@ static void run_updater_win() // 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; + return false; } #endif //_WIN32 @@ -728,7 +731,6 @@ void GUI_App::post_init() this->check_updates(false); CallAfter([this] { bool cw_showed = this->config_wizard_startup(); - this->preset_updater->slic3r_update_notify(); this->preset_updater->sync(preset_bundle); if (! cw_showed) { // The CallAfter is needed as well, without it, GL extensions did not show. @@ -736,10 +738,15 @@ void GUI_App::post_init() // sees something else than "we want something" on the first start. 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(); }); } @@ -1124,26 +1131,30 @@ bool GUI_App::on_init_inner() Bind(EVT_SLIC3R_VERSION_ONLINE, [this](const wxCommandEvent& evt) { app_config->set("version_online", into_u8(evt.GetString())); 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()))) { - 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(); - if (this->plater_ != nullptr && app_config->get("notify_testing_release") == "1") { - if (*Semver::parse(SLIC3R_VERSION) < *Semver::parse(into_u8(evt.GetString()))) { - this->plater_->get_notification_manager()->push_notification(NotificationType::NewAlphaAvailable); - } - } - }); - Bind(EVT_SLIC3R_BETA_VERSION_ONLINE, [this](const wxCommandEvent& evt) { - app_config->save(); - if (this->plater_ != nullptr && app_config->get("notify_testing_release") == "1") { - 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); + if (this->plater_ != nullptr && app_config->get("notify_release") == "all") { + std::string evt_string = into_u8(evt.GetString()); + 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 + , Slic3r::format(_u8L("New prerelease version %1% is available."), evt_string) + , _u8L("See Releases page.") + , [](wxEvtHandler* evnthndlr) {wxGetApp().open_browser_with_warning_dialog("https://github.com/prusa3d/PrusaSlicer/releases"); return true; } + ); } } }); diff --git a/src/slic3r/GUI/NotificationManager.cpp b/src/slic3r/GUI/NotificationManager.cpp index 0af8e32f5..bcef85107 100644 --- a/src/slic3r/GUI/NotificationManager.cpp +++ b/src/slic3r/GUI/NotificationManager.cpp @@ -41,12 +41,6 @@ const NotificationManager::NotificationData NotificationManager::basic_notificat 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, _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\"") }, @@ -61,6 +55,8 @@ const NotificationManager::NotificationData NotificationManager::basic_notificat {NotificationType::UndoDesktopIntegrationFail, NotificationLevel::WarningNotificationLevel, 10, _u8L("Undo desktop integration failed.") }, {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::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 diff --git a/src/slic3r/GUI/NotificationManager.hpp b/src/slic3r/GUI/NotificationManager.hpp index 6c50f6407..f162182dc 100644 --- a/src/slic3r/GUI/NotificationManager.hpp +++ b/src/slic3r/GUI/NotificationManager.hpp @@ -150,7 +150,7 @@ public: // Push a NotificationType::CustomNotification with NotificationLevel::RegularNotificationLevel and 10s fade out interval. void push_notification(const std::string& text, int timestamp = 0); // 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 = "", std::function callback = std::function(), int timestamp = 0); // Pushes basic_notification with delay. See push_delayed_notification_data. @@ -720,7 +720,7 @@ private: case NotificationLevel::ErrorNotificationLevel: return 0; case NotificationLevel::WarningNotificationLevel: return 0; - case NotificationLevel::ImportantNotificationLevel: return 0; + case NotificationLevel::ImportantNotificationLevel: return 20; case NotificationLevel::ProgressBarNotificationLevel: return 2; case NotificationLevel::PrintInfoShortNotificationLevel: return 5; case NotificationLevel::RegularNotificationLevel: return 10; diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index c73fd4064..332de64cb 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -141,14 +141,6 @@ void PreferencesDialog::build(size_t selected_tab) option = Option(def, "background_processing"); 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(); // Please keep in sync with ConfigWizard diff --git a/src/slic3r/GUI/UpdateDialogs.cpp b/src/slic3r/GUI/UpdateDialogs.cpp index d617ca660..552ca43be 100644 --- a/src/slic3r/GUI/UpdateDialogs.cpp +++ b/src/slic3r/GUI/UpdateDialogs.cpp @@ -26,7 +26,7 @@ namespace GUI { 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 std::string CONFIG_UPDATE_WIKI_URL("https://github.com/prusa3d/PrusaSlicer/wiki/Slic3r-PE-1.40-configuration-update"); diff --git a/src/slic3r/Utils/PresetUpdater.cpp b/src/slic3r/Utils/PresetUpdater.cpp index 76ecc76d9..1d9d287bb 100644 --- a/src/slic3r/Utils/PresetUpdater.cpp +++ b/src/slic3r/Utils/PresetUpdater.cpp @@ -137,8 +137,7 @@ struct Updates wxDEFINE_EVENT(EVT_SLIC3R_VERSION_ONLINE, wxCommandEvent); -wxDEFINE_EVENT(EVT_SLIC3R_ALPHA_VERSION_ONLINE, wxCommandEvent); -wxDEFINE_EVENT(EVT_SLIC3R_BETA_VERSION_ONLINE, wxCommandEvent); +wxDEFINE_EVENT(EVT_SLIC3R_EXPERIMENTAL_VERSION_ONLINE, wxCommandEvent); struct PresetUpdater::priv { @@ -189,7 +188,7 @@ PresetUpdater::priv::priv() // Pull relevant preferences from AppConfig 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(); 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); else version = body; - if (!Semver::parse(version)) { - BOOST_LOG_TRIVIAL(warning) << format("Received invalid contents from `%1%`: Not a correct semver: `%2%`", SLIC3R_APP_NAME, version); + boost::optional release_version = Semver::parse(version); + if (!release_version) { + BOOST_LOG_TRIVIAL(error) << format("Received invalid contents from `%1%`: Not a correct semver: `%2%`", SLIC3R_APP_NAME, version); return; } 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); // alpha / beta version + std::vector prerelease_versions; size_t nexn_nl_pos = first_nl_pos; while (nexn_nl_pos != std::string::npos && body.size() > nexn_nl_pos + 1) { 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=") { version = line.substr(6); 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; } - BOOST_LOG_TRIVIAL(info) << format("Got %1% online version of alpha release: `%2%`. Sending to GUI thread...", SLIC3R_APP_NAME, version); - wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_ALPHA_VERSION_ONLINE); - evt->SetString(GUI::from_u8(version)); - GUI::wxGetApp().QueueEvent(evt); - + prerelease_versions.emplace_back(version); // beta } else if (line.substr(0, 5) == "beta=") { version = line.substr(5); 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; } - BOOST_LOG_TRIVIAL(info) << format("Got %1% online version of beta release: `%2%`. Sending to GUI thread...", SLIC3R_APP_NAME, version); - wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_BETA_VERSION_ONLINE); - evt->SetString(GUI::from_u8(version)); - GUI::wxGetApp().QueueEvent(evt); + prerelease_versions.emplace_back(version); } } + // find recent version that is newer than last full release. + boost::optional recent_version; + for (const std::string& ver_string : prerelease_versions) { + boost::optional 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. @@ -741,8 +750,8 @@ void PresetUpdater::sync(PresetBundle *preset_bundle) void PresetUpdater::slic3r_update_notify() { - if (! p->enabled_version_check) { return; } - + if (! p->enabled_version_check) + return; auto* app_config = GUI::wxGetApp().app_config; const auto ver_online_str = app_config->get("version_online"); 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); notification.ShowModal(); if (notification.disable_version_check()) { - app_config->set("version_check", "0"); + app_config->set("notify_release", "none"); p->enabled_version_check = false; } } diff --git a/src/slic3r/Utils/PresetUpdater.hpp b/src/slic3r/Utils/PresetUpdater.hpp index 085aaa4a6..1313c3df8 100644 --- a/src/slic3r/Utils/PresetUpdater.hpp +++ b/src/slic3r/Utils/PresetUpdater.hpp @@ -63,7 +63,6 @@ private: }; wxDECLARE_EVENT(EVT_SLIC3R_VERSION_ONLINE, wxCommandEvent); -wxDECLARE_EVENT(EVT_SLIC3R_ALPHA_VERSION_ONLINE, wxCommandEvent); -wxDECLARE_EVENT(EVT_SLIC3R_BETA_VERSION_ONLINE, wxCommandEvent); +wxDECLARE_EVENT(EVT_SLIC3R_EXPERIMENTAL_VERSION_ONLINE, wxCommandEvent); } #endif