Merge branch 'dk_dwnldr_fixes'

This commit is contained in:
David Kocik 2023-02-17 09:32:40 +01:00
commit 30bae9f803
12 changed files with 281 additions and 124 deletions

View File

@ -1315,10 +1315,12 @@ PageUpdate::PageUpdate(ConfigWizard *parent)
box_presets->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent &event) { this->preset_update = event.IsChecked(); }); box_presets->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent &event) { this->preset_update = event.IsChecked(); });
} }
namespace DownloaderUtils namespace DownloaderUtils
{ {
namespace {
#ifdef _WIN32 #ifdef _WIN32
wxString get_downloads_path() wxString get_downloads_path()
{ {
wxString ret; wxString ret;
@ -1330,7 +1332,6 @@ namespace DownloaderUtils
CoTaskMemFree(path); CoTaskMemFree(path);
return ret; return ret;
} }
#elif __APPLE__ #elif __APPLE__
wxString get_downloads_path() wxString get_downloads_path()
{ {
@ -1348,9 +1349,8 @@ namespace DownloaderUtils
} }
return wxString(); return wxString();
} }
#endif #endif
}
Worker::Worker(wxWindow* parent) Worker::Worker(wxWindow* parent)
: wxBoxSizer(wxHORIZONTAL) : wxBoxSizer(wxHORIZONTAL)
, m_parent(parent) , m_parent(parent)
@ -1432,16 +1432,16 @@ PageDownloader::PageDownloader(ConfigWizard* parent)
))); )));
#endif #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); m_downloader = new DownloaderUtils::Worker(this);
append(downloader); append(m_downloader);
downloader->allow(box_allow_value); m_downloader->allow(box_allow_value);
} }
bool PageDownloader::on_finish_downloader() const 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/* = {}*/) 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__ #ifdef __linux__
// Desktop integration on 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(); 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() || page_downloader->downloader->get_perform_registration_linux()) if (page_welcome->integrate_desktop())
DesktopIntegrationDialog::perform_desktop_integration(page_downloader->downloader->get_perform_registration_linux()); DesktopIntegrationDialog::perform_desktop_integration();
if (page_downloader->m_downloader->get_perform_registration_linux())
DesktopIntegrationDialog::perform_downloader_desktop_integration();
#endif #endif
// Decide whether to create snapshot based on run_reason and the reset profile checkbox // Decide whether to create snapshot based on run_reason and the reset profile checkbox

View File

@ -4,6 +4,8 @@
#include <memory> #include <memory>
#include <wx/dialog.h> #include <wx/dialog.h>
#include <wx/sizer.h>
#include <wx/textctrl.h>
#include "GUI_Utils.hpp" #include "GUI_Utils.hpp"
@ -14,6 +16,36 @@ class PresetUpdater;
namespace GUI { 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 class ConfigWizard: public DPIDialog
{ {

View File

@ -10,12 +10,10 @@
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/log/trivial.hpp> #include <boost/log/trivial.hpp>
#include <wx/sizer.h>
#include <wx/panel.h> #include <wx/panel.h>
#include <wx/button.h> #include <wx/button.h>
#include <wx/choice.h> #include <wx/choice.h>
#include <wx/spinctrl.h> #include <wx/spinctrl.h>
#include <wx/textctrl.h>
#include <wx/listbox.h> #include <wx/listbox.h>
#include <wx/checklst.h> #include <wx/checklst.h>
#include <wx/radiobut.h> #include <wx/radiobut.h>
@ -418,44 +416,10 @@ struct PageUpdate: ConfigWizardPage
PageUpdate(ConfigWizard *parent); 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 struct PageDownloader : ConfigWizardPage
{ {
DownloaderUtils::Worker* downloader{ nullptr }; DownloaderUtils::Worker* m_downloader { nullptr };
PageDownloader(ConfigWizard* parent); PageDownloader(ConfigWizard* parent);

View File

@ -218,9 +218,9 @@ bool DesktopIntegrationDialog::integration_possible()
{ {
return true; 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 // Path to appimage
const char *appimage_env = std::getenv("APPIMAGE"); const char *appimage_env = std::getenv("APPIMAGE");
std::string excutable_path; 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.")); 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); wxGetApp().plater()->get_notification_manager()->push_notification(NotificationType::DesktopIntegrationSuccess);
} }
void DesktopIntegrationDialog::undo_desktop_intgration() void DesktopIntegrationDialog::undo_desktop_intgration()
@ -487,15 +455,162 @@ void DesktopIntegrationDialog::undo_desktop_intgration()
std::remove(path.c_str()); 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); 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::vector<std::string>target_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() void DesktopIntegrationDialog::undo_downloader_registration()
{ {
const AppConfig *app_config = wxGetApp().app_config; 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")); wxButton *btn_perform = new wxButton(this, wxID_ANY, _L("Perform"));
btn_szr->Add(btn_perform, 0, wxALL, 10); 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){ if (can_undo){
wxButton *btn_undo = new wxButton(this, wxID_ANY, _L("Undo")); wxButton *btn_undo = new wxButton(this, wxID_ANY, _L("Undo"));

View File

@ -29,10 +29,11 @@ public:
// if perform_downloader: // if perform_downloader:
// Creates Destktop files for PrusaSlicer downloader feature // Creates Destktop files for PrusaSlicer downloader feature
// Regiters PrusaSlicer to start on prusaslicer:// URL // 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. // Deletes Desktop files and icons for both PrusaSlicer and GcodeViewer at paths stored in App Config.
static void undo_desktop_intgration(); static void undo_desktop_intgration();
static void perform_downloader_desktop_integration();
static void undo_downloader_registration(); static void undo_downloader_registration();
private: private:

View File

@ -137,13 +137,30 @@ void FileGet::priv::get_perform()
std::string extension = boost::filesystem::extension(dest_path); std::string extension = boost::filesystem::extension(dest_path);
std::string just_filename = m_filename.substr(0, m_filename.size() - extension.size()); std::string just_filename = m_filename.substr(0, m_filename.size() - extension.size());
std::string final_filename = just_filename; std::string final_filename = just_filename;
// Find unsed filename
size_t version = 0; try {
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"))) 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; wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_ERROR);
final_filename = just_filename + "(" + std::to_string(version) + ")"; evt->SetString(e.what());
evt->SetInt(m_id);
m_evt_handler->QueueEvent(evt);
return;
} }
m_filename = final_filename + extension; m_filename = final_filename + extension;
m_tmp_path = m_dest_folder / (m_filename + "." + std::to_string(get_current_pid()) + ".download"); m_tmp_path = m_dest_folder / (m_filename + "." + std::to_string(get_current_pid()) + ".download");

View File

@ -172,16 +172,20 @@ FileArchiveDialog::FileArchiveDialog(wxWindow* parent_window, mz_zip_archive* ar
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX) wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX)
, m_selected_paths (selected_paths) , m_selected_paths (selected_paths)
{ {
#ifdef _WIN32
wxGetApp().UpdateDarkUI(this);
#else
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif
int em = em_unit(); int em = em_unit();
wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL);
m_avc = new ArchiveViewCtrl(this, wxSize(45 * em, 30 * em));
m_avc = new ArchiveViewCtrl(this, wxSize(60 * em, 30 * em)); wxDataViewColumn* toggle_column = m_avc->AppendToggleColumn(L"\u2714", 0, wxDATAVIEW_CELL_ACTIVATABLE, 6 * em);
m_avc->AppendToggleColumn(L"\u2714", 0, wxDATAVIEW_CELL_ACTIVATABLE, 6 * em);
m_avc->AppendTextColumn("filename", 1); m_avc->AppendTextColumn("filename", 1);
std::vector<std::shared_ptr<ArchiveViewNode>> stack; std::vector<std::shared_ptr<ArchiveViewNode>> stack;
std::function<void(std::vector<std::shared_ptr<ArchiveViewNode> >&, size_t)> reduce_stack = [] (std::vector<std::shared_ptr<ArchiveViewNode>>& stack, size_t size) { std::function<void(std::vector<std::shared_ptr<ArchiveViewNode> >&, size_t)> reduce_stack = [] (std::vector<std::shared_ptr<ArchiveViewNode>>& 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 // 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(); }); 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) for (const boost::filesystem::path& path : filtered_entries)
{ {
std::shared_ptr<ArchiveViewNode> parent(nullptr); std::shared_ptr<ArchiveViewNode> parent(nullptr);
adjust_stack(path, stack); depth = std::max(depth, adjust_stack(path, stack));
if (!stack.empty()) if (!stack.empty())
parent = stack.back(); parent = stack.back();
if (std::regex_match(path.extension().string(), pattern_drop)) { // this leaves out non-compatible files 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? 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); 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_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_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(); 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_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); }); 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(m_avc, 1, wxEXPAND | wxALL, 10);
topSizer->Add(btn_sizer, 0, wxEXPAND | wxALL, 10); topSizer->Add(btn_sizer, 0, wxEXPAND | wxALL, 10);
this->SetMinSize(wxSize(80 * em, 30 * em));
this->SetSizer(topSizer); 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<wxButton*>(FindWindowByLabel(id, this)));
} }
void FileArchiveDialog::on_dpi_changed(const wxRect& suggested_rect) 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 }) //for (auto btn : { m_save_btn, m_transfer_btn, m_discard_btn })
// if (btn) btn->msw_rescale(); // if (btn) btn->msw_rescale();
const wxSize& size = wxSize(70 * em, 30 * em); const wxSize& size = wxSize(45 * em, 40 * em);
SetMinSize(size); SetSize(size);
//m_tree->Rescale(em); //m_tree->Rescale(em);
Fit(); Fit();

View File

@ -79,7 +79,6 @@
#include "DesktopIntegrationDialog.hpp" #include "DesktopIntegrationDialog.hpp"
#include "SendSystemInfoDialog.hpp" #include "SendSystemInfoDialog.hpp"
#include "Downloader.hpp" #include "Downloader.hpp"
#include "ConfigWizard_private.hpp"
#include "BitmapCache.hpp" #include "BitmapCache.hpp"
#include "Notebook.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")) 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; BOOST_LOG_TRIVIAL(error) << "Recieved command to open URL, but it is not allowed in app configuration. URL: " << url;
return; return;
} }
@ -3081,11 +3081,11 @@ void GUI_App::show_downloader_registration_dialog()
), SLIC3R_APP_NAME, SLIC3R_VERSION) ), SLIC3R_APP_NAME, SLIC3R_VERSION)
, true, wxYES_NO); , true, wxYES_NO);
if (msg.ShowModal() == wxID_YES) { if (msg.ShowModal() == wxID_YES) {
auto downloader = new DownloaderUtils::Worker(nullptr); auto downloader_worker = new DownloaderUtils::Worker(nullptr);
downloader->perform_register(app_config->get("url_downloader_dest")); downloader_worker->perform_register(app_config->get("url_downloader_dest"));
#ifdef __linux__ #ifdef __linux__
if (downloader->get_perform_registration_linux()) if (downloader_worker->get_perform_registration_linux())
DesktopIntegrationDialog::perform_desktop_integration(true); DesktopIntegrationDialog::perform_downloader_desktop_integration();
#endif // __linux__ #endif // __linux__
} else { } else {
app_config->set("downloader_url_registered", "0"); app_config->set("downloader_url_registered", "0");

View File

@ -306,8 +306,8 @@ public:
Plater* plater(); Plater* plater();
const Plater* plater() const; const Plater* plater() const;
Model& model(); Model& model();
NotificationManager * notification_manager(); NotificationManager* notification_manager();
GalleryDialog * gallery_dialog(); GalleryDialog * gallery_dialog();
Downloader* downloader(); Downloader* downloader();
// Parameters extracted from the command line to be passed to GUI after initialization. // Parameters extracted from the command line to be passed to GUI after initialization.

View File

@ -120,7 +120,9 @@ enum class NotificationType
// Short meesage to fill space between start and finish of export // Short meesage to fill space between start and finish of export
ExportOngoing, ExportOngoing,
// Progressbar of download from prusaslicer:// url // Progressbar of download from prusaslicer:// url
URLDownload URLDownload,
// MacOS specific - PS comes forward even when downloader is not allowed
URLNotRegistered,
}; };
class NotificationManager class NotificationManager
@ -916,6 +918,16 @@ private:
{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::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) { //{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; }}, // 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.") },

View File

@ -10,7 +10,7 @@
#include "ButtonsDescription.hpp" #include "ButtonsDescription.hpp"
#include "OG_CustomCtrl.hpp" #include "OG_CustomCtrl.hpp"
#include "GLCanvas3D.hpp" #include "GLCanvas3D.hpp"
#include "ConfigWizard_private.hpp" #include "ConfigWizard.hpp"
#include <boost/dll/runtime_symbol_info.hpp> #include <boost/dll/runtime_symbol_info.hpp>
@ -712,7 +712,7 @@ void PreferencesDialog::accept(wxEvent&)
return; return;
#ifdef __linux__ #ifdef __linux__
if( downloader->get_perform_registration_linux()) if( downloader->get_perform_registration_linux())
DesktopIntegrationDialog::perform_desktop_integration(true); DesktopIntegrationDialog::perform_downloader_desktop_integration();
#endif // __linux__ #endif // __linux__
} }

View File

@ -59,7 +59,7 @@ class PreferencesDialog : public DPIDialog
wxColourPickerCtrl* m_mode_advanced { nullptr }; wxColourPickerCtrl* m_mode_advanced { nullptr };
wxColourPickerCtrl* m_mode_expert { nullptr }; wxColourPickerCtrl* m_mode_expert { nullptr };
DownloaderUtils::Worker* downloader{ nullptr }; DownloaderUtils::Worker* downloader { nullptr };
wxBookCtrlBase* tabs {nullptr}; wxBookCtrlBase* tabs {nullptr};