diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index 1cf647ed7f..35292d803b 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -1315,10 +1315,12 @@ PageUpdate::PageUpdate(ConfigWizard *parent) box_presets->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent &event) { this->preset_update = event.IsChecked(); }); } + + namespace DownloaderUtils { +namespace { #ifdef _WIN32 - wxString get_downloads_path() { wxString ret; @@ -1330,7 +1332,6 @@ namespace DownloaderUtils CoTaskMemFree(path); return ret; } - #elif __APPLE__ wxString get_downloads_path() { @@ -1348,9 +1349,8 @@ namespace DownloaderUtils } return wxString(); } - #endif - + } Worker::Worker(wxWindow* parent) : wxBoxSizer(wxHORIZONTAL) , m_parent(parent) @@ -1432,16 +1432,16 @@ PageDownloader::PageDownloader(ConfigWizard* parent) ))); #endif - box_allow_downloads->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& event) { this->downloader->allow(event.IsChecked()); }); + box_allow_downloads->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& event) { this->m_downloader->allow(event.IsChecked()); }); - downloader = new DownloaderUtils::Worker(this); - append(downloader); - downloader->allow(box_allow_value); + m_downloader = new DownloaderUtils::Worker(this); + append(m_downloader); + m_downloader->allow(box_allow_value); } bool PageDownloader::on_finish_downloader() const { - return downloader->on_finish(); + return m_downloader->on_finish(); } bool DownloaderUtils::Worker::perform_register(const std::string& path_override/* = {}*/) @@ -3035,9 +3035,11 @@ bool ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese #ifdef __linux__ // Desktop integration on Linux - BOOST_LOG_TRIVIAL(debug) << "ConfigWizard::priv::apply_config integrate_desktop" << page_welcome->integrate_desktop() << " perform_registration_linux " << page_downloader->downloader->get_perform_registration_linux(); - if (page_welcome->integrate_desktop() || page_downloader->downloader->get_perform_registration_linux()) - DesktopIntegrationDialog::perform_desktop_integration(page_downloader->downloader->get_perform_registration_linux()); + BOOST_LOG_TRIVIAL(debug) << "ConfigWizard::priv::apply_config integrate_desktop" << page_welcome->integrate_desktop() << " perform_registration_linux " << page_downloader->m_downloader->get_perform_registration_linux(); + if (page_welcome->integrate_desktop()) + DesktopIntegrationDialog::perform_desktop_integration(); + if (page_downloader->m_downloader->get_perform_registration_linux()) + DesktopIntegrationDialog::perform_downloader_desktop_integration(); #endif // Decide whether to create snapshot based on run_reason and the reset profile checkbox diff --git a/src/slic3r/GUI/ConfigWizard.hpp b/src/slic3r/GUI/ConfigWizard.hpp index 88d2e2d7c3..dcd0297ae9 100644 --- a/src/slic3r/GUI/ConfigWizard.hpp +++ b/src/slic3r/GUI/ConfigWizard.hpp @@ -4,6 +4,8 @@ #include #include +#include +#include #include "GUI_Utils.hpp" @@ -14,6 +16,36 @@ class PresetUpdater; namespace GUI { +namespace DownloaderUtils { + class Worker : public wxBoxSizer + { + wxWindow* m_parent{ nullptr }; + wxTextCtrl* m_input_path{ nullptr }; + bool downloader_checked{ false }; +#ifdef __linux__ + bool perform_registration_linux{ false }; +#endif // __linux__ + + void deregister(); + + public: + Worker(wxWindow* parent); + ~Worker() {} + + void allow(bool allow_) { downloader_checked = allow_; } + bool is_checked() const { return downloader_checked; } + wxString path_name() const { return m_input_path ? m_input_path->GetValue() : wxString(); } + + void set_path_name(wxString name); + void set_path_name(const std::string& name); + + bool on_finish(); + bool perform_register(const std::string& path_override = {}); +#ifdef __linux__ + bool get_perform_registration_linux() { return perform_registration_linux; } +#endif // __linux__ + }; +} class ConfigWizard: public DPIDialog { diff --git a/src/slic3r/GUI/ConfigWizard_private.hpp b/src/slic3r/GUI/ConfigWizard_private.hpp index c7c6e5152b..2dc2c2e233 100644 --- a/src/slic3r/GUI/ConfigWizard_private.hpp +++ b/src/slic3r/GUI/ConfigWizard_private.hpp @@ -10,12 +10,10 @@ #include #include -#include #include #include #include #include -#include #include #include #include @@ -418,44 +416,10 @@ struct PageUpdate: ConfigWizardPage PageUpdate(ConfigWizard *parent); }; -namespace DownloaderUtils { - wxString get_downloads_path(); - -class Worker : public wxBoxSizer -{ - wxWindow* m_parent {nullptr}; - wxTextCtrl* m_input_path {nullptr}; - bool downloader_checked {false}; -#ifdef __linux__ - bool perform_registration_linux { false }; -#endif // __linux__ - - void deregister(); - -public: - Worker(wxWindow* parent); - ~Worker(){} - - void allow(bool allow_) { downloader_checked = allow_; } - bool is_checked() const { return downloader_checked; } - wxString path_name() const { return m_input_path ? m_input_path->GetValue() : wxString(); } - - void set_path_name(wxString name); - void set_path_name(const std::string& name); - - bool on_finish(); - bool perform_register(const std::string& path_override = {}); -#ifdef __linux__ - bool get_perform_registration_linux() { return perform_registration_linux; } -#endif // __linux__ -}; - -} - struct PageDownloader : ConfigWizardPage { - DownloaderUtils::Worker* downloader{ nullptr }; + DownloaderUtils::Worker* m_downloader { nullptr }; PageDownloader(ConfigWizard* parent); diff --git a/src/slic3r/GUI/DesktopIntegrationDialog.cpp b/src/slic3r/GUI/DesktopIntegrationDialog.cpp index a37b76459a..62e8411533 100644 --- a/src/slic3r/GUI/DesktopIntegrationDialog.cpp +++ b/src/slic3r/GUI/DesktopIntegrationDialog.cpp @@ -218,9 +218,9 @@ bool DesktopIntegrationDialog::integration_possible() { return true; } -void DesktopIntegrationDialog::perform_desktop_integration(bool perform_downloader) +void DesktopIntegrationDialog::perform_desktop_integration() { - BOOST_LOG_TRIVIAL(debug) << "performing desktop integration. With downloader integration: " << perform_downloader; + BOOST_LOG_TRIVIAL(debug) << "performing desktop integration."; // Path to appimage const char *appimage_env = std::getenv("APPIMAGE"); std::string excutable_path; @@ -423,38 +423,6 @@ void DesktopIntegrationDialog::perform_desktop_integration(bool perform_download show_error(nullptr, _L("Performing desktop integration failed - could not create Gcodeviewer desktop file. PrusaSlicer desktop file was probably created successfully.")); } } - - if (perform_downloader) - { - std::string desktop_file_downloader = GUI::format( - "[Desktop Entry]\n" - "Name=PrusaSlicer URL Protocol%1%\n" - "Exec=\"%3%\" --single-instance %%u\n" - "Icon=PrusaSlicer%4%\n" - "Terminal=false\n" - "Type=Application\n" - "MimeType=x-scheme-handler/prusaslicer;\n" - "StartupNotify=false\n" - , name_suffix, version_suffix, excutable_path, version_suffix); - - // desktop file for downloader as part of main app - std::string desktop_path = GUI::format("%1%/applications/PrusaSlicerURLProtocol%2%.desktop", target_dir_desktop, version_suffix); - if (create_desktop_file(desktop_path, desktop_file_downloader)) { - // save path to desktop file - app_config->set("desktop_integration_URL_path", desktop_path); - // finish registration on mime type - std::string command = GUI::format("xdg-mime default PrusaSlicerURLProtocol%1%.desktop x-scheme-handler/prusaslicer", version_suffix); - BOOST_LOG_TRIVIAL(debug) << "system command: " << command; - int r = system(command.c_str()); - BOOST_LOG_TRIVIAL(debug) << "system result: " << r; - - } else { - BOOST_LOG_TRIVIAL(error) << "Performing desktop integration failed - could not create URL Protocol desktop file"; - show_error(nullptr, _L("Performing desktop integration failed - could not create URL Protocol desktop file.")); - return; - } - } - wxGetApp().plater()->get_notification_manager()->push_notification(NotificationType::DesktopIntegrationSuccess); } void DesktopIntegrationDialog::undo_desktop_intgration() @@ -487,15 +455,162 @@ void DesktopIntegrationDialog::undo_desktop_intgration() std::remove(path.c_str()); } } - // URL Protocol - path = std::string(app_config->get("desktop_integration_URL_path")); - if (!path.empty()) { - BOOST_LOG_TRIVIAL(debug) << "removing " << path; - std::remove(path.c_str()); - } wxGetApp().plater()->get_notification_manager()->push_notification(NotificationType::UndoDesktopIntegrationSuccess); } +void DesktopIntegrationDialog::perform_downloader_desktop_integration() +{ + BOOST_LOG_TRIVIAL(debug) << "performing downloader desktop integration."; + // Path to appimage + const char* appimage_env = std::getenv("APPIMAGE"); + std::string excutable_path; + if (appimage_env) { + try { + excutable_path = boost::filesystem::canonical(boost::filesystem::path(appimage_env)).string(); + } + catch (std::exception&) { + BOOST_LOG_TRIVIAL(error) << "Performing downloader desktop integration failed - boost::filesystem::canonical did not return appimage path."; + show_error(nullptr, _L("Performing downloader desktop integration failed - boost::filesystem::canonical did not return appimage path.")); + return; + } + } + else { + // not appimage - find executable + excutable_path = boost::dll::program_location().string(); + //excutable_path = wxStandardPaths::Get().GetExecutablePath().string(); + BOOST_LOG_TRIVIAL(debug) << "non-appimage path to executable: " << excutable_path; + if (excutable_path.empty()) + { + BOOST_LOG_TRIVIAL(error) << "Performing downloader desktop integration failed - no executable found."; + show_error(nullptr, _L("Performing downloader desktop integration failed - Could not find executable.")); + return; + } + } + // Escape ' characters in appimage, other special symbols will be esacaped in desktop file by 'excutable_path' + //boost::replace_all(excutable_path, "'", "'\\''"); + excutable_path = escape_string(excutable_path); + + // Find directories icons and applications + // $XDG_DATA_HOME defines the base directory relative to which user specific data files should be stored. + // If $XDG_DATA_HOME is either not set or empty, a default equal to $HOME/.local/share should be used. + // $XDG_DATA_DIRS defines the preference-ordered set of base directories to search for data files in addition to the $XDG_DATA_HOME base directory. + // The directories in $XDG_DATA_DIRS should be seperated with a colon ':'. + // If $XDG_DATA_DIRS is either not set or empty, a value equal to /usr/local/share/:/usr/share/ should be used. + std::vectortarget_candidates; + resolve_path_from_var("XDG_DATA_HOME", target_candidates); + resolve_path_from_var("XDG_DATA_DIRS", target_candidates); + + AppConfig* app_config = wxGetApp().app_config; + // suffix string to create different desktop file for alpha, beta. + + std::string version_suffix; + std::string name_suffix; + std::string version(SLIC3R_VERSION); + if (version.find("alpha") != std::string::npos) + { + version_suffix = "-alpha"; + name_suffix = " - alpha"; + } + else if (version.find("beta") != std::string::npos) + { + version_suffix = "-beta"; + name_suffix = " - beta"; + } + + // theme path to icon destination + std::string icon_theme_path; + std::string icon_theme_dirs; + + if (platform_flavor() == PlatformFlavor::LinuxOnChromium) { + icon_theme_path = "hicolor/96x96/apps/"; + icon_theme_dirs = "/hicolor/96x96/apps"; + } + + std::string target_dir_desktop; + + // desktop file + // iterate thru target_candidates to find applications folder + + std::string desktop_file_downloader = GUI::format( + "[Desktop Entry]\n" + "Name=PrusaSlicer URL Protocol%1%\n" + "Exec=\"%2%\" --single-instance %%u\n" + "Terminal=false\n" + "Type=Application\n" + "MimeType=x-scheme-handler/prusaslicer;\n" + "StartupNotify=false\n" + "NoDisplay=true\n" + , name_suffix, excutable_path); + + // desktop file for downloader as part of main app + std::string desktop_path = GUI::format("%1%/applications/PrusaSlicerURLProtocol%2%.desktop", target_dir_desktop, version_suffix); + if (create_desktop_file(desktop_path, desktop_file_downloader)) { + // save path to desktop file + app_config->set("desktop_integration_URL_path", desktop_path); + // finish registration on mime type + std::string command = GUI::format("xdg-mime default PrusaSlicerURLProtocol%1%.desktop x-scheme-handler/prusaslicer", version_suffix); + BOOST_LOG_TRIVIAL(debug) << "system command: " << command; + int r = system(command.c_str()); + BOOST_LOG_TRIVIAL(debug) << "system result: " << r; + + } + + bool candidate_found = false; + for (size_t i = 0; i < target_candidates.size(); ++i) { + if (contains_path_dir(target_candidates[i], "applications")) { + target_dir_desktop = target_candidates[i]; + // Write slicer desktop file + std::string path = GUI::format("%1%/applications/PrusaSlicerURLProtocol%2%.desktop", target_dir_desktop, version_suffix); + if (create_desktop_file(path, desktop_file_downloader)) { + app_config->set("desktop_integration_URL_path", path); + candidate_found = true; + BOOST_LOG_TRIVIAL(debug) << "PrusaSlicerURLProtocol.desktop file installation success."; + break; + } + else { + // write failed - try another path + BOOST_LOG_TRIVIAL(debug) << "Attempt to PrusaSlicerURLProtocol.desktop file installation failed. failed path: " << target_candidates[i]; + target_dir_desktop.clear(); + } + } + } + // if all failed - try creating default home folder + if (!candidate_found) { + // create $HOME/.local/share + create_path(boost::nowide::narrow(wxFileName::GetHomeDir()), ".local/share/applications"); + // create desktop file + target_dir_desktop = GUI::format("%1%/.local/share", wxFileName::GetHomeDir()); + std::string path = GUI::format("%1%/applications/PrusaSlicerURLProtocol%2%.desktop", target_dir_desktop, version_suffix); + if (contains_path_dir(target_dir_desktop, "applications")) { + if (!create_desktop_file(path, desktop_file_downloader)) { + // Desktop file not written - end desktop integration + BOOST_LOG_TRIVIAL(error) << "Performing downloader desktop integration failed - could not create desktop file."; + return; + } + app_config->set("desktop_integration_URL_path", path); + } + else { + // Desktop file not written - end desktop integration + BOOST_LOG_TRIVIAL(error) << "Performing downloader desktop integration failed because the application directory was not found."; + return; + } + } + assert(!target_dir_desktop.empty()); + if (target_dir_desktop.empty()) { + // Desktop file not written - end desktop integration + BOOST_LOG_TRIVIAL(error) << "Performing downloader desktop integration failed because the application directory was not found."; + show_error(nullptr, _L("Performing downloader desktop integration failed because the application directory was not found.")); + return; + } + + // finish registration on mime type + std::string command = GUI::format("xdg-mime default PrusaSlicerURLProtocol%1%.desktop x-scheme-handler/prusaslicer", version_suffix); + BOOST_LOG_TRIVIAL(debug) << "system command: " << command; + int r = system(command.c_str()); + BOOST_LOG_TRIVIAL(debug) << "system result: " << r; + + wxGetApp().plater()->get_notification_manager()->push_notification(NotificationType::DesktopIntegrationSuccess); +} void DesktopIntegrationDialog::undo_downloader_registration() { const AppConfig *app_config = wxGetApp().app_config; @@ -532,7 +647,7 @@ DesktopIntegrationDialog::DesktopIntegrationDialog(wxWindow *parent) wxButton *btn_perform = new wxButton(this, wxID_ANY, _L("Perform")); btn_szr->Add(btn_perform, 0, wxALL, 10); - btn_perform->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { DesktopIntegrationDialog::perform_desktop_integration(false); EndModal(wxID_ANY); }); + btn_perform->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { DesktopIntegrationDialog::perform_desktop_integration(); EndModal(wxID_ANY); }); if (can_undo){ wxButton *btn_undo = new wxButton(this, wxID_ANY, _L("Undo")); diff --git a/src/slic3r/GUI/DesktopIntegrationDialog.hpp b/src/slic3r/GUI/DesktopIntegrationDialog.hpp index 08c984083b..19cff1fd85 100644 --- a/src/slic3r/GUI/DesktopIntegrationDialog.hpp +++ b/src/slic3r/GUI/DesktopIntegrationDialog.hpp @@ -29,10 +29,11 @@ public: // if perform_downloader: // Creates Destktop files for PrusaSlicer downloader feature // Regiters PrusaSlicer to start on prusaslicer:// URL - static void perform_desktop_integration(bool perform_downloader); + static void perform_desktop_integration(); // Deletes Desktop files and icons for both PrusaSlicer and GcodeViewer at paths stored in App Config. static void undo_desktop_intgration(); + static void perform_downloader_desktop_integration(); static void undo_downloader_registration(); private: diff --git a/src/slic3r/GUI/DownloaderFileGet.cpp b/src/slic3r/GUI/DownloaderFileGet.cpp index 0a1e7ce251..ee407afddd 100644 --- a/src/slic3r/GUI/DownloaderFileGet.cpp +++ b/src/slic3r/GUI/DownloaderFileGet.cpp @@ -137,13 +137,30 @@ void FileGet::priv::get_perform() std::string extension = boost::filesystem::extension(dest_path); std::string just_filename = m_filename.substr(0, m_filename.size() - extension.size()); std::string final_filename = just_filename; - - size_t version = 0; - while (boost::filesystem::exists(m_dest_folder / (final_filename + extension)) || boost::filesystem::exists(m_dest_folder / (final_filename + extension + "." + std::to_string(get_current_pid()) + ".download"))) + // Find unsed filename + try { + size_t version = 0; + while (boost::filesystem::exists(m_dest_folder / (final_filename + extension)) || boost::filesystem::exists(m_dest_folder / (final_filename + extension + "." + std::to_string(get_current_pid()) + ".download"))) + { + ++version; + if (version > 999) { + wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_ERROR); + evt->SetString(GUI::format_wxstr(L"Failed to find suitable filename. Last name: %1%." , (m_dest_folder / (final_filename + extension)).string())); + evt->SetInt(m_id); + m_evt_handler->QueueEvent(evt); + return; + } + final_filename = GUI::format("%1%(%2%)", just_filename, std::to_string(version)); + } + } catch (const boost::filesystem::filesystem_error& e) { - ++version; - final_filename = just_filename + "(" + std::to_string(version) + ")"; + wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_ERROR); + evt->SetString(e.what()); + evt->SetInt(m_id); + m_evt_handler->QueueEvent(evt); + return; } + m_filename = final_filename + extension; m_tmp_path = m_dest_folder / (m_filename + "." + std::to_string(get_current_pid()) + ".download"); diff --git a/src/slic3r/GUI/FileArchiveDialog.cpp b/src/slic3r/GUI/FileArchiveDialog.cpp index 2b861692a4..7337258cb9 100644 --- a/src/slic3r/GUI/FileArchiveDialog.cpp +++ b/src/slic3r/GUI/FileArchiveDialog.cpp @@ -172,16 +172,20 @@ FileArchiveDialog::FileArchiveDialog(wxWindow* parent_window, mz_zip_archive* ar wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX) , m_selected_paths (selected_paths) { +#ifdef _WIN32 + wxGetApp().UpdateDarkUI(this); +#else + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); +#endif + int em = em_unit(); wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL); - - m_avc = new ArchiveViewCtrl(this, wxSize(60 * em, 30 * em)); - m_avc->AppendToggleColumn(L"\u2714", 0, wxDATAVIEW_CELL_ACTIVATABLE, 6 * em); + m_avc = new ArchiveViewCtrl(this, wxSize(45 * em, 30 * em)); + wxDataViewColumn* toggle_column = m_avc->AppendToggleColumn(L"\u2714", 0, wxDATAVIEW_CELL_ACTIVATABLE, 6 * em); m_avc->AppendTextColumn("filename", 1); - std::vector> stack; std::function >&, size_t)> reduce_stack = [] (std::vector>& stack, size_t size) { @@ -233,40 +237,51 @@ FileArchiveDialog::FileArchiveDialog(wxWindow* parent_window, mz_zip_archive* ar } // sorting files will help adjust_stack function to not create multiple same folders std::sort(filtered_entries.begin(), filtered_entries.end(), [](const boost::filesystem::path& p1, const boost::filesystem::path& p2){ return p1.string() > p2.string(); }); + size_t entry_count = 0; + size_t depth = 1; for (const boost::filesystem::path& path : filtered_entries) { std::shared_ptr parent(nullptr); - adjust_stack(path, stack); + depth = std::max(depth, adjust_stack(path, stack)); if (!stack.empty()) parent = stack.back(); if (std::regex_match(path.extension().string(), pattern_drop)) { // this leaves out non-compatible files m_avc->get_model()->AddFile(parent, GUI::format_wxstr(path.filename().string()), false)->set_fullpath(/*std::move(path)*/path); // filename string to wstring? + entry_count++; } } + if (entry_count == 1) + on_all_button(); + + toggle_column->SetWidth((4 + depth) * em); + wxBoxSizer* btn_sizer = new wxBoxSizer(wxHORIZONTAL); - wxButton* btn_all = new wxButton(this, wxID_ANY, "All"); + wxButton* btn_all = new wxButton(this, wxID_ANY, _L("All")); btn_all->Bind(wxEVT_BUTTON, [this](wxCommandEvent& evt) { on_all_button(); }); - btn_sizer->Add(btn_all, 0, wxLeft); + btn_sizer->Add(btn_all, 0); - wxButton* btn_none = new wxButton(this, wxID_ANY, "None"); + wxButton* btn_none = new wxButton(this, wxID_ANY, _L("None")); btn_none->Bind(wxEVT_BUTTON, [this](wxCommandEvent& evt) { on_none_button(); }); - btn_sizer->Add(btn_none, 0, wxLeft); + btn_sizer->Add(btn_none, 0, wxLEFT, em); btn_sizer->AddStretchSpacer(); - wxButton* btn_run = new wxButton(this, wxID_OK, "Open"); + wxButton* btn_run = new wxButton(this, wxID_OK, _L("Open")); btn_run->Bind(wxEVT_BUTTON, [this](wxCommandEvent& evt) { on_open_button(); }); - btn_sizer->Add(btn_run, 0, wxRIGHT); + btn_sizer->Add(btn_run, 0, wxRIGHT, em); - wxButton* cancel_btn = new wxButton(this, wxID_CANCEL, "Cancel"); + wxButton* cancel_btn = new wxButton(this, wxID_CANCEL, _L("Cancel")); cancel_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& evt) { this->EndModal(wxID_CANCEL); }); - btn_sizer->Add(cancel_btn, 0, wxRIGHT); + btn_sizer->Add(cancel_btn, 0, wxRIGHT, em); topSizer->Add(m_avc, 1, wxEXPAND | wxALL, 10); topSizer->Add(btn_sizer, 0, wxEXPAND | wxALL, 10); - this->SetMinSize(wxSize(80 * em, 30 * em)); this->SetSizer(topSizer); + SetMinSize(wxSize(40 * em, 30 * em)); + + for (const wxString& id : {_L("All"), _L("None"), _L("Open"), _L("Cancel") }) + wxGetApp().UpdateDarkUI(static_cast(FindWindowByLabel(id, this))); } void FileArchiveDialog::on_dpi_changed(const wxRect& suggested_rect) @@ -277,9 +292,8 @@ void FileArchiveDialog::on_dpi_changed(const wxRect& suggested_rect) //for (auto btn : { m_save_btn, m_transfer_btn, m_discard_btn }) // if (btn) btn->msw_rescale(); - const wxSize& size = wxSize(70 * em, 30 * em); - SetMinSize(size); - + const wxSize& size = wxSize(45 * em, 40 * em); + SetSize(size); //m_tree->Rescale(em); Fit(); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index a4cfc0cb95..520f67aed1 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -79,7 +79,6 @@ #include "DesktopIntegrationDialog.hpp" #include "SendSystemInfoDialog.hpp" #include "Downloader.hpp" -#include "ConfigWizard_private.hpp" #include "BitmapCache.hpp" #include "Notebook.hpp" @@ -2890,6 +2889,7 @@ void GUI_App::MacOpenURL(const wxString& url) { if (app_config && !app_config->get_bool("downloader_url_registered")) { + notification_manager()->push_notification(NotificationType::URLNotRegistered); BOOST_LOG_TRIVIAL(error) << "Recieved command to open URL, but it is not allowed in app configuration. URL: " << url; return; } @@ -3081,11 +3081,11 @@ void GUI_App::show_downloader_registration_dialog() ), SLIC3R_APP_NAME, SLIC3R_VERSION) , true, wxYES_NO); if (msg.ShowModal() == wxID_YES) { - auto downloader = new DownloaderUtils::Worker(nullptr); - downloader->perform_register(app_config->get("url_downloader_dest")); + auto downloader_worker = new DownloaderUtils::Worker(nullptr); + downloader_worker->perform_register(app_config->get("url_downloader_dest")); #ifdef __linux__ - if (downloader->get_perform_registration_linux()) - DesktopIntegrationDialog::perform_desktop_integration(true); + if (downloader_worker->get_perform_registration_linux()) + DesktopIntegrationDialog::perform_downloader_desktop_integration(); #endif // __linux__ } else { app_config->set("downloader_url_registered", "0"); diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 1a58bd8094..3f8d47fd77 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -306,8 +306,8 @@ public: Plater* plater(); const Plater* plater() const; Model& model(); - NotificationManager * notification_manager(); - GalleryDialog * gallery_dialog(); + NotificationManager* notification_manager(); + GalleryDialog * gallery_dialog(); Downloader* downloader(); // Parameters extracted from the command line to be passed to GUI after initialization. diff --git a/src/slic3r/GUI/NotificationManager.hpp b/src/slic3r/GUI/NotificationManager.hpp index b3a39a936f..778f99bfa3 100644 --- a/src/slic3r/GUI/NotificationManager.hpp +++ b/src/slic3r/GUI/NotificationManager.hpp @@ -120,7 +120,9 @@ enum class NotificationType // Short meesage to fill space between start and finish of export ExportOngoing, // Progressbar of download from prusaslicer:// url - URLDownload + URLDownload, + // MacOS specific - PS comes forward even when downloader is not allowed + URLNotRegistered, }; class NotificationManager @@ -916,6 +918,16 @@ private: {NotificationType::UndoDesktopIntegrationFail, NotificationLevel::WarningNotificationLevel, 10, _u8L("Undo desktop integration failed.") }, {NotificationType::ExportOngoing, NotificationLevel::RegularNotificationLevel, 0, _u8L("Exporting.") }, + {NotificationType::URLNotRegistered + , NotificationLevel::RegularNotificationLevel + , 10 + , _u8L("PrusaSlicer recieved a download request from Printables.com, but it's not allowed. You can allow it") + , _u8L("here.") + , [](wxEvtHandler* evnthndlr) { + wxGetApp().open_preferences("downloader_url_registered", "Other"); + 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::NewAppAvailable, NotificationLevel::ImportantNotificationLevel, 20, _u8L("New vesion of PrusaSlicer is available.", _u8L("Download page.") }, diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index 40c5314ee4..a47e6065f2 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -10,7 +10,7 @@ #include "ButtonsDescription.hpp" #include "OG_CustomCtrl.hpp" #include "GLCanvas3D.hpp" -#include "ConfigWizard_private.hpp" +#include "ConfigWizard.hpp" #include @@ -712,7 +712,7 @@ void PreferencesDialog::accept(wxEvent&) return; #ifdef __linux__ if( downloader->get_perform_registration_linux()) - DesktopIntegrationDialog::perform_desktop_integration(true); + DesktopIntegrationDialog::perform_downloader_desktop_integration(); #endif // __linux__ } diff --git a/src/slic3r/GUI/Preferences.hpp b/src/slic3r/GUI/Preferences.hpp index 15a9576921..4ae93f6f9a 100644 --- a/src/slic3r/GUI/Preferences.hpp +++ b/src/slic3r/GUI/Preferences.hpp @@ -59,7 +59,7 @@ class PreferencesDialog : public DPIDialog wxColourPickerCtrl* m_mode_advanced { nullptr }; wxColourPickerCtrl* m_mode_expert { nullptr }; - DownloaderUtils::Worker* downloader{ nullptr }; + DownloaderUtils::Worker* downloader { nullptr }; wxBookCtrlBase* tabs {nullptr};