From b7f0b51c3bfa22011ecd9f2edac428a35cabbc11 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 19 Aug 2024 10:04:56 +0200 Subject: [PATCH 1/4] AppUpdater: Read option "action" and on value "browser" open url in browser. Increased min size. --- src/slic3r/GUI/GUI_App.cpp | 8 ++++++-- src/slic3r/GUI/UpdateDialogs.cpp | 8 +++++++- src/slic3r/GUI/UpdateDialogs.hpp | 2 +- src/slic3r/Utils/AppUpdater.cpp | 22 ++++++++++------------ src/slic3r/Utils/AppUpdater.hpp | 5 +++++ 5 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 905478207e..8dc35e2e65 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -3227,7 +3227,7 @@ wxString GUI_App::current_language_code_safe() const void GUI_App::open_web_page_localized(const std::string &http_address) { - open_browser_with_warning_dialog(http_address + "&lng=" + this->current_language_code_safe(), nullptr, false); + open_browser_with_warning_dialog(from_u8(http_address + "&lng=") + this->current_language_code_safe(), nullptr, false); } // If we are switching from the FFF-preset to the SLA, we should to control the printed objects if they have a part(s). @@ -3701,7 +3701,7 @@ void GUI_App::app_updater(bool from_user) assert(!app_data.target_path.empty()); // dialog with new version info - AppUpdateAvailableDialog dialog(*Semver::parse(SLIC3R_VERSION), *app_data.version, from_user); + AppUpdateAvailableDialog dialog(*Semver::parse(SLIC3R_VERSION), *app_data.version, from_user, app_data.action == AppUpdaterURLAction::AUUA_OPEN_IN_BROWSER); auto dialog_result = dialog.ShowModal(); // checkbox "do not show again" if (dialog.disable_version_check()) { @@ -3711,6 +3711,10 @@ void GUI_App::app_updater(bool from_user) if (dialog_result != wxID_OK) { return; } + if (app_data.action == AppUpdaterURLAction::AUUA_OPEN_IN_BROWSER) { + open_browser_with_warning_dialog(from_u8(app_data.url)); + return; + } // dialog with new version download (installer or app dependent on system) including path selection AppUpdateDownloadDialog dwnld_dlg(*app_data.version, app_data.target_path); dialog_result = dwnld_dlg.ShowModal(); diff --git a/src/slic3r/GUI/UpdateDialogs.cpp b/src/slic3r/GUI/UpdateDialogs.cpp index ac6bf58009..ea948e4e2c 100644 --- a/src/slic3r/GUI/UpdateDialogs.cpp +++ b/src/slic3r/GUI/UpdateDialogs.cpp @@ -99,7 +99,7 @@ bool MsgUpdateSlic3r::disable_version_check() const wxSize AppUpdateAvailableDialog::AUAD_size; // AppUpdater -AppUpdateAvailableDialog::AppUpdateAvailableDialog(const Semver& ver_current, const Semver& ver_online, bool from_user) +AppUpdateAvailableDialog::AppUpdateAvailableDialog(const Semver& ver_current, const Semver& ver_online, bool from_user, bool browser_on_next) : MsgDialog(nullptr, _(L("App Update available")), wxString::Format(_(L("New version of %s is available.\nDo you wish to download it?")), SLIC3R_APP_NAME)) { auto* versions = new wxFlexGridSizer(1, 0, VERT_SPACING); @@ -116,6 +116,12 @@ AppUpdateAvailableDialog::AppUpdateAvailableDialog(const Semver& ver_current, co } content_sizer->AddSpacer(VERT_SPACING); + if (browser_on_next) + { + content_sizer->Add(new wxStaticText(this, wxID_ANY, _(L("Clicking \'Next\' will open a browser window to select your download.")))); + content_sizer->AddSpacer(VERT_SPACING); + } + AUAD_size = content_sizer->GetSize(); diff --git a/src/slic3r/GUI/UpdateDialogs.hpp b/src/slic3r/GUI/UpdateDialogs.hpp index ef0cac1d7e..432da9812b 100644 --- a/src/slic3r/GUI/UpdateDialogs.hpp +++ b/src/slic3r/GUI/UpdateDialogs.hpp @@ -46,7 +46,7 @@ private: class AppUpdateAvailableDialog : public MsgDialog { public: - AppUpdateAvailableDialog(const Semver& ver_current, const Semver& ver_online, bool from_user); + AppUpdateAvailableDialog(const Semver& ver_current, const Semver& ver_online, bool from_user, bool browser_on_next); AppUpdateAvailableDialog(AppUpdateAvailableDialog&&) = delete; AppUpdateAvailableDialog(const AppUpdateAvailableDialog&) = delete; AppUpdateAvailableDialog& operator=(AppUpdateAvailableDialog&&) = delete; diff --git a/src/slic3r/Utils/AppUpdater.cpp b/src/slic3r/Utils/AppUpdater.cpp index f8ad97905f..d3016eace7 100644 --- a/src/slic3r/Utils/AppUpdater.cpp +++ b/src/slic3r/Utils/AppUpdater.cpp @@ -45,7 +45,7 @@ namespace { bool res = GUI::create_process(path, std::wstring(), msg); if (!res) { std::string full_message = GUI::format(_u8L("Running downloaded instaler of %1% has failed:\n%2%"), SLIC3R_APP_NAME, msg); - BOOST_LOG_TRIVIAL(error) << full_message; // lm: maybe UI error msg? // dk: bellow. (maybe some general show error evt would be better?) + BOOST_LOG_TRIVIAL(error) << full_message; wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_APP_DOWNLOAD_FAILED); evt->SetString(full_message); GUI::wxGetApp().QueueEvent(evt); @@ -165,7 +165,7 @@ AppUpdater::priv::priv() : if (!downloads_path.empty()) { m_default_dest_folder = std::move(downloads_path); } - BOOST_LOG_TRIVIAL(trace) << "App updater default download path: " << m_default_dest_folder; //lm:Is this an error? // dk: changed to trace + BOOST_LOG_TRIVIAL(trace) << "App updater default download path: " << m_default_dest_folder; } @@ -236,7 +236,7 @@ boost::filesystem::path AppUpdater::priv::download_file(const DownloadAppData& d } std::string error_message; - bool res = http_get_file(data.url, 130 * 1024 * 1024 //2.4.0 windows installer is 65MB //lm:I don't know, but larger. The binaries will grow. // dk: changed to 130, to have 100% more space. We should put this information into version file. + bool res = http_get_file(data.url, 256 * 1024 * 1024 // on_progress , [&last_gui_progress, expected_size](Http::Progress progress) { // size check @@ -333,10 +333,6 @@ void AppUpdater::priv::version_check(const std::string& version_check_url) } , error_message ); - //lm:In case the internet is not available, it will report no updates if run by user. - // We might save a flag that we don't know or try to run the version_check again, reporting - // the failure. - // dk: changed to download version every time. Dialog will show if m_triggered_by_user. if (!res) { std::string message = GUI::format("Downloading %1% version file has failed:\n%2%", SLIC3R_APP_NAME, error_message); BOOST_LOG_TRIVIAL(error) << message; @@ -390,19 +386,21 @@ void AppUpdater::priv::parse_version_string(const std::string& body) #else "release:linux" #endif -//lm:Related to the ifdefs. We should also support BSD, which behaves similar to Linux in most cases. -// Unless you have a reason not to, I would consider doing _WIN32, elif __APPLE__, else ... Not just here. -// dk: so its ok now or we need to specify BSD? ) { for (const auto& data : section.second) { if (data.first == "url") { new_data.url = data.second.data(); new_data.target_path = m_default_dest_folder / AppUpdater::get_filename_from_url(new_data.url); BOOST_LOG_TRIVIAL(info) << format("parsing version string: url: %1%", new_data.url); - } else if (data.first == "size"){ + } else if (data.first == "size") { new_data.size = std::stoi(data.second.data()); BOOST_LOG_TRIVIAL(info) << format("parsing version string: expected size: %1%", new_data.size); - } + } else if (data.first == "action") { + std::string action = data.second.data(); + if (action == "browser") { + new_data.action = AppUpdaterURLAction::AUUA_OPEN_IN_BROWSER; + } + } } } diff --git a/src/slic3r/Utils/AppUpdater.hpp b/src/slic3r/Utils/AppUpdater.hpp index 93555f3126..476d48241d 100644 --- a/src/slic3r/Utils/AppUpdater.hpp +++ b/src/slic3r/Utils/AppUpdater.hpp @@ -19,6 +19,10 @@ namespace Slic3r { std::string get_downloads_path_mac(); #endif //__APPLE__ +enum class AppUpdaterURLAction { + AUUA_DOWNLOAD, + AUUA_OPEN_IN_BROWSER +}; struct DownloadAppData { std::string url; @@ -26,6 +30,7 @@ struct DownloadAppData boost::optional version; size_t size; boost::filesystem::path target_path; + AppUpdaterURLAction action { AppUpdaterURLAction::AUUA_DOWNLOAD }; }; class AppUpdater From 447dd1568138e1d950798d07c17afcc125e080d1 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 19 Aug 2024 13:50:59 +0200 Subject: [PATCH 2/4] Fix of incorrect usage of wxString in fopen in AppUpdater and Downloader. --- src/slic3r/GUI/DownloaderFileGet.cpp | 4 ++-- src/slic3r/Utils/AppUpdater.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/DownloaderFileGet.cpp b/src/slic3r/GUI/DownloaderFileGet.cpp index 7a7c7044c2..cbb0ae4663 100644 --- a/src/slic3r/GUI/DownloaderFileGet.cpp +++ b/src/slic3r/GUI/DownloaderFileGet.cpp @@ -187,9 +187,9 @@ void FileGet::priv::get_perform() FILE* file; // open file for writting if (m_written == 0) - file = fopen(temp_path_wstring.c_str(), "wb"); + file = fopen(into_u8(temp_path_wstring).c_str(), "wb"); else - file = fopen(temp_path_wstring.c_str(), "ab"); + file = fopen(into_u8(temp_path_wstring).c_str(), "ab"); //assert(file != NULL); if (file == NULL) { diff --git a/src/slic3r/Utils/AppUpdater.cpp b/src/slic3r/Utils/AppUpdater.cpp index d3016eace7..9c12eafd16 100644 --- a/src/slic3r/Utils/AppUpdater.cpp +++ b/src/slic3r/Utils/AppUpdater.cpp @@ -222,7 +222,7 @@ boost::filesystem::path AppUpdater::priv::download_file(const DownloadAppData& d tmp_path += format(".%1%%2%", std::to_string(GUI::GLCanvas3D::timestamp_now()), ".download"); FILE* file; wxString temp_path_wstring(tmp_path.wstring()); - file = fopen(temp_path_wstring.c_str(), "wb"); + file = fopen(GUI::into_u8(temp_path_wstring).c_str(), "wb"); assert(file != NULL); if (file == NULL) { std::string line1 = GUI::format(_u8L("Download from %1% couldn't start:"), data.url); From abea96fd8a971d378a43a4fc8c8d6ac5b4b2660e Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 27 Aug 2024 14:19:48 +0200 Subject: [PATCH 3/4] Force opening hyperlink on App updater. Refactored open_browser_with_warning_dialog due to poor readability - no changes to funcionality. --- src/slic3r/GUI/GUI_App.cpp | 88 ++++++++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 33 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 8dc35e2e65..815dc42069 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -3544,42 +3544,64 @@ bool GUI_App::check_updates(const bool invoked_by_user) // Applicaiton will continue. return true; } +namespace { +bool open_dialog_hyperlink_checkbox(wxWindow* parent, AppConfig* app_config) +{ + RichMessageDialog dialog(parent, _L("Open hyperlink in default browser?"), _L("PrusaSlicer: Open hyperlink"), wxICON_QUESTION | wxYES_NO); + dialog.ShowCheckBox(_L("Remember my choice")); + auto answer = dialog.ShowModal(); + bool launch = answer == wxID_YES; + if (dialog.IsCheckBoxChecked()) { + wxString preferences_item = _L("Suppress to open hyperlink in browser"); + wxString msg = + _L("PrusaSlicer will remember your choice.") + "\n\n" + + _L("You will not be asked about it again on hyperlinks hovering.") + "\n\n" + + format_wxstr(_L("Visit \"Preferences\" and check \"%1%\"\nto changes your choice."), preferences_item); + MessageDialog msg_dlg(parent, msg, _L("PrusaSlicer: Don't ask me again"), wxOK | wxCANCEL | wxICON_INFORMATION); + if (msg_dlg.ShowModal() == wxID_CANCEL) + return false; + app_config->set("suppress_hyperlinks", answer == wxID_NO ? "1" : "0"); + } + return launch; +} +bool open_dialog_hyperlink(wxWindow* parent) +{ + MessageDialog dialog(parent, _L("Open hyperlink in default browser?"), _L("PrusaSlicer: Open hyperlink"), wxICON_QUESTION | wxYES_NO); + return dialog.ShowModal() == wxID_YES; +} +} bool GUI_App::open_browser_with_warning_dialog(const wxString& url, wxWindow* parent/* = nullptr*/, bool force_remember_choice /*= true*/, int flags/* = 0*/) { + enum class SupressHyperLinksOption{ + SHLO_UNCHECKED, + SHLO_ALWAYS_SUPRESS, + SHLO_ALWAYS_ALLOW + }; + bool empty = app_config->get("suppress_hyperlinks").empty(); + bool checked = app_config->get_bool("suppress_hyperlinks"); + SupressHyperLinksOption opt_val = + (empty + ? SupressHyperLinksOption::SHLO_UNCHECKED + : (checked + ? SupressHyperLinksOption::SHLO_ALWAYS_SUPRESS + : SupressHyperLinksOption::SHLO_ALWAYS_ALLOW)); bool launch = true; - - // warning dialog containes a "Remember my choice" checkbox - std::string option_key = "suppress_hyperlinks"; - if (force_remember_choice || app_config->get(option_key).empty()) { - if (app_config->get(option_key).empty()) { - RichMessageDialog dialog(parent, _L("Open hyperlink in default browser?"), _L("PrusaSlicer: Open hyperlink"), wxICON_QUESTION | wxYES_NO); - dialog.ShowCheckBox(_L("Remember my choice")); - auto answer = dialog.ShowModal(); - launch = answer == wxID_YES; - if (dialog.IsCheckBoxChecked()) { - wxString preferences_item = _L("Suppress to open hyperlink in browser"); - wxString msg = - _L("PrusaSlicer will remember your choice.") + "\n\n" + - _L("You will not be asked about it again on hyperlinks hovering.") + "\n\n" + - format_wxstr(_L("Visit \"Preferences\" and check \"%1%\"\nto changes your choice."), preferences_item); - - MessageDialog msg_dlg(parent, msg, _L("PrusaSlicer: Don't ask me again"), wxOK | wxCANCEL | wxICON_INFORMATION); - if (msg_dlg.ShowModal() == wxID_CANCEL) - return false; - app_config->set(option_key, answer == wxID_NO ? "1" : "0"); - } - } - if (launch) - launch = !app_config->get_bool(option_key); - } - // warning dialog doesn't containe a "Remember my choice" checkbox - // and will be shown only when "Suppress to open hyperlink in browser" is ON. - else if (app_config->get_bool(option_key)) { - MessageDialog dialog(parent, _L("Open hyperlink in default browser?"), _L("PrusaSlicer: Open hyperlink"), wxICON_QUESTION | wxYES_NO); - launch = dialog.ShowModal() == wxID_YES; - } - + if (opt_val == SupressHyperLinksOption::SHLO_UNCHECKED) { + // no previous action from user + // open dialog with remember checkbox + launch = open_dialog_hyperlink_checkbox(parent, app_config); + } else if (opt_val == SupressHyperLinksOption::SHLO_ALWAYS_ALLOW) { + // user already set checkbox to always open + launch = true; + } else if (opt_val == SupressHyperLinksOption::SHLO_ALWAYS_SUPRESS && force_remember_choice) { + // user already set checkbox or preferences to always supress + launch = false; + } else if (opt_val == SupressHyperLinksOption::SHLO_ALWAYS_SUPRESS && !force_remember_choice) { + // user already set checkbox or preferences to always supress but it is overriden + // no checkbox in dialog + launch = open_dialog_hyperlink(parent); + } return launch && wxLaunchDefaultBrowser(url, flags); } @@ -3712,7 +3734,7 @@ void GUI_App::app_updater(bool from_user) return; } if (app_data.action == AppUpdaterURLAction::AUUA_OPEN_IN_BROWSER) { - open_browser_with_warning_dialog(from_u8(app_data.url)); + open_browser_with_warning_dialog(from_u8(app_data.url), nullptr, false); return; } // dialog with new version download (installer or app dependent on system) including path selection From ddba05828d83434dd232df2dec2e3f118c509c39 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Thu, 29 Aug 2024 16:02:38 +0200 Subject: [PATCH 4/4] Fixed couple of encoding issues --- src/slic3r/GUI/DownloaderFileGet.cpp | 11 +++-------- src/slic3r/GUI/WifiConfigDialog.cpp | 2 +- src/slic3r/Utils/AppUpdater.cpp | 3 +-- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/slic3r/GUI/DownloaderFileGet.cpp b/src/slic3r/GUI/DownloaderFileGet.cpp index cbb0ae4663..172f734b67 100644 --- a/src/slic3r/GUI/DownloaderFileGet.cpp +++ b/src/slic3r/GUI/DownloaderFileGet.cpp @@ -176,26 +176,21 @@ void FileGet::priv::get_perform() } boost::filesystem::path dest_path = m_dest_folder / m_filename; - - wxString temp_path_wstring(m_tmp_path.wstring()); - - //std::cout << "dest_path: " << dest_path.string() << std::endl; - //std::cout << "m_tmp_path: " << m_tmp_path.string() << std::endl; BOOST_LOG_TRIVIAL(info) << GUI::format("Starting download from %1% to %2%. Temp path is %3%",m_url, dest_path, m_tmp_path); FILE* file; // open file for writting if (m_written == 0) - file = fopen(into_u8(temp_path_wstring).c_str(), "wb"); + file = boost::nowide::fopen(m_tmp_path.string().c_str(), "wb"); else - file = fopen(into_u8(temp_path_wstring).c_str(), "ab"); + file = boost::nowide::fopen(m_tmp_path.string().c_str(), "ab"); //assert(file != NULL); if (file == NULL) { wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_ERROR); // TRN %1% = file path - evt->SetString(GUI::format_wxstr(_L("Can't create file at %1%"), temp_path_wstring)); + evt->SetString(GUI::format_wxstr(_L("Can't create file at %1%"), m_tmp_path.string())); evt->SetInt(m_id); m_evt_handler->QueueEvent(evt); return; diff --git a/src/slic3r/GUI/WifiConfigDialog.cpp b/src/slic3r/GUI/WifiConfigDialog.cpp index d40293b3f9..0edcd0552f 100644 --- a/src/slic3r/GUI/WifiConfigDialog.cpp +++ b/src/slic3r/GUI/WifiConfigDialog.cpp @@ -294,7 +294,7 @@ void WifiConfigDialog::on_ok(wxCommandEvent& e) m_used_path = boost::nowide::widen(file_path.string()); FILE* file; - file = fopen(file_path.string().c_str(), "w"); + file = boost::nowide::fopen(file_path.string().c_str(), "w"); if (file == NULL) { BOOST_LOG_TRIVIAL(error) << "Failed to write to file " << file_path; // TODO show error diff --git a/src/slic3r/Utils/AppUpdater.cpp b/src/slic3r/Utils/AppUpdater.cpp index 9c12eafd16..8089e952f1 100644 --- a/src/slic3r/Utils/AppUpdater.cpp +++ b/src/slic3r/Utils/AppUpdater.cpp @@ -221,8 +221,7 @@ boost::filesystem::path AppUpdater::priv::download_file(const DownloadAppData& d boost::filesystem::path tmp_path = dest_path; tmp_path += format(".%1%%2%", std::to_string(GUI::GLCanvas3D::timestamp_now()), ".download"); FILE* file; - wxString temp_path_wstring(tmp_path.wstring()); - file = fopen(GUI::into_u8(temp_path_wstring).c_str(), "wb"); + file = boost::nowide::fopen(tmp_path.string().c_str(), "wb"); assert(file != NULL); if (file == NULL) { std::string line1 = GUI::format(_u8L("Download from %1% couldn't start:"), data.url);