mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-13 09:47:58 -06:00
support cura:// and thingiverse
This commit is contained in:
parent
6519e850ef
commit
524efcfcca
4 changed files with 66 additions and 17 deletions
|
@ -239,6 +239,12 @@ inline bool is_thingiverse_link(const std::string& url) {
|
||||||
const std::regex url_regex("(http|https)://www.thingiverse.com", std::regex_constants::icase);
|
const std::regex url_regex("(http|https)://www.thingiverse.com", std::regex_constants::icase);
|
||||||
return std::regex_match(url, url_regex);
|
return std::regex_match(url, url_regex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sanitize a string to be used as a filename
|
||||||
|
inline std::string sanitize_filename(const std::string &filename){
|
||||||
|
const std::regex special_chars("[/\\\\:*?\"<>|]");
|
||||||
|
return std::regex_replace(filename, special_chars, "_");
|
||||||
|
}
|
||||||
// File path / name / extension splitting utilities, working with UTF-8,
|
// File path / name / extension splitting utilities, working with UTF-8,
|
||||||
// to be published to Perl.
|
// to be published to Perl.
|
||||||
namespace PerlUtils {
|
namespace PerlUtils {
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "format.hpp"
|
#include "format.hpp"
|
||||||
#include "GUI.hpp"
|
#include "GUI.hpp"
|
||||||
#include "I18N.hpp"
|
#include "I18N.hpp"
|
||||||
|
#include "libslic3r/Utils.hpp"
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
@ -124,7 +125,15 @@ FileGet::priv::priv(int ID, std::string&& url, const std::string& filename, wxEv
|
||||||
, m_dest_folder(dest_folder)
|
, m_dest_folder(dest_folder)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
std::string extract_remote_filename(const std::string& str) {
|
||||||
|
std::regex r("filename=\"([^\"]*)\"");
|
||||||
|
std::smatch match;
|
||||||
|
if (std::regex_search(str.begin(), str.end(), match, r)) {
|
||||||
|
return match.str(1);
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
void FileGet::priv::get_perform()
|
void FileGet::priv::get_perform()
|
||||||
{
|
{
|
||||||
assert(m_evt_handler);
|
assert(m_evt_handler);
|
||||||
|
@ -135,10 +144,11 @@ void FileGet::priv::get_perform()
|
||||||
m_stopped = false;
|
m_stopped = false;
|
||||||
|
|
||||||
// open dest file
|
// open dest file
|
||||||
|
std::string extension;
|
||||||
if (m_written == 0)
|
if (m_written == 0)
|
||||||
{
|
{
|
||||||
boost::filesystem::path dest_path = m_dest_folder / m_filename;
|
boost::filesystem::path dest_path = m_dest_folder / m_filename;
|
||||||
std::string extension = boost::filesystem::extension(dest_path);
|
extension = dest_path.extension().string();
|
||||||
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
|
// Find unsed filename
|
||||||
|
@ -164,10 +174,10 @@ void FileGet::priv::get_perform()
|
||||||
m_evt_handler->QueueEvent(evt);
|
m_evt_handler->QueueEvent(evt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_filename = final_filename + extension;
|
|
||||||
|
|
||||||
m_tmp_path = m_dest_folder / (m_filename + "." + std::to_string(get_current_pid()) + ".download");
|
m_filename = sanitize_filename(final_filename + extension);
|
||||||
|
|
||||||
|
m_tmp_path = m_dest_folder / (m_filename + "." + std::to_string(get_current_pid()) + ".download");
|
||||||
|
|
||||||
wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_NAME_CHANGE);
|
wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_NAME_CHANGE);
|
||||||
evt->SetString(boost::nowide::widen(m_filename));
|
evt->SetString(boost::nowide::widen(m_filename));
|
||||||
|
@ -175,7 +185,9 @@ void FileGet::priv::get_perform()
|
||||||
m_evt_handler->QueueEvent(evt);
|
m_evt_handler->QueueEvent(evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::filesystem::path dest_path = m_dest_folder / m_filename;
|
boost::filesystem::path dest_path;
|
||||||
|
if(!extension.empty())
|
||||||
|
dest_path = m_dest_folder / m_filename;
|
||||||
|
|
||||||
wxString temp_path_wstring(m_tmp_path.wstring());
|
wxString temp_path_wstring(m_tmp_path.wstring());
|
||||||
|
|
||||||
|
@ -208,6 +220,19 @@ void FileGet::priv::get_perform()
|
||||||
Http::get(m_url)
|
Http::get(m_url)
|
||||||
.size_limit(DOWNLOAD_SIZE_LIMIT) //more?
|
.size_limit(DOWNLOAD_SIZE_LIMIT) //more?
|
||||||
.set_range(range_string)
|
.set_range(range_string)
|
||||||
|
.on_header_callback([&](std::string header) {
|
||||||
|
if(dest_path.empty()) {
|
||||||
|
std::string filename = extract_remote_filename(header);
|
||||||
|
if (!filename.empty()) {
|
||||||
|
m_filename = filename;
|
||||||
|
dest_path = m_dest_folder / m_filename;
|
||||||
|
wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_NAME_CHANGE);
|
||||||
|
evt->SetString(boost::nowide::widen(m_filename));
|
||||||
|
evt->SetInt(m_id);
|
||||||
|
m_evt_handler->QueueEvent(evt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
.on_progress([&](Http::Progress progress, bool& cancel) {
|
.on_progress([&](Http::Progress progress, bool& cancel) {
|
||||||
// to prevent multiple calls into following ifs (m_cancel / m_pause)
|
// to prevent multiple calls into following ifs (m_cancel / m_pause)
|
||||||
if (m_stopped){
|
if (m_stopped){
|
||||||
|
@ -292,14 +317,18 @@ void FileGet::priv::get_perform()
|
||||||
//}
|
//}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
/*
|
// Orca: thingiverse need this
|
||||||
if (m_written < body.size())
|
if (m_written < body.size())
|
||||||
{
|
{
|
||||||
// this code should never be entered. As there should be on_progress call after last bit downloaded.
|
// this code should never be entered. As there should be on_progress call after last bit downloaded.
|
||||||
std::string part_for_write = body.substr(m_written);
|
std::string part_for_write = body.substr(m_written);
|
||||||
fwrite(part_for_write.c_str(), 1, part_for_write.size(), file);
|
fwrite(part_for_write.c_str(), 1, part_for_write.size(), file);
|
||||||
}
|
|
||||||
*/
|
wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_PROGRESS);
|
||||||
|
evt->SetString(std::to_string(100));
|
||||||
|
evt->SetInt(m_id);
|
||||||
|
m_evt_handler->QueueEvent(evt);
|
||||||
|
}
|
||||||
fclose(file);
|
fclose(file);
|
||||||
boost::filesystem::rename(m_tmp_path, dest_path);
|
boost::filesystem::rename(m_tmp_path, dest_path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -746,7 +746,7 @@ wxBoxSizer *PreferencesDialog::create_item_checkbox(wxString title, wxWindow *pa
|
||||||
}
|
}
|
||||||
|
|
||||||
wxBoxSizer* PreferencesDialog::create_item_button(
|
wxBoxSizer* PreferencesDialog::create_item_button(
|
||||||
wxString title, wxString title2, wxWindow* parent, wxString tooltip, wxString tooltip2, std::function<void()> onclick)
|
wxString title, wxString title2, wxWindow* parent, wxString tooltip, wxString tooltip2, std::function<void()> onclick, bool button_on_left/* = false*/)
|
||||||
{
|
{
|
||||||
wxBoxSizer *m_sizer_checkbox = new wxBoxSizer(wxHORIZONTAL);
|
wxBoxSizer *m_sizer_checkbox = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
|
||||||
|
@ -776,8 +776,13 @@ wxBoxSizer* PreferencesDialog::create_item_button(
|
||||||
|
|
||||||
m_button_download->Bind(wxEVT_BUTTON, [this, onclick](auto &e) { onclick(); });
|
m_button_download->Bind(wxEVT_BUTTON, [this, onclick](auto &e) { onclick(); });
|
||||||
|
|
||||||
m_sizer_checkbox->Add(m_staticTextPath, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
|
if (button_on_left) {
|
||||||
m_sizer_checkbox->Add(m_button_download, 0, wxALL, FromDIP(5));
|
m_sizer_checkbox->Add(m_button_download, 0, wxALL, FromDIP(5));
|
||||||
|
m_sizer_checkbox->Add(m_staticTextPath, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
|
||||||
|
} else {
|
||||||
|
m_sizer_checkbox->Add(m_staticTextPath, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
|
||||||
|
m_sizer_checkbox->Add(m_button_download, 0, wxALL, FromDIP(5));
|
||||||
|
}
|
||||||
|
|
||||||
return m_sizer_checkbox;
|
return m_sizer_checkbox;
|
||||||
}
|
}
|
||||||
|
@ -1059,6 +1064,7 @@ wxWindow* PreferencesDialog::create_general_page()
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
auto title_associate_file = create_item_title(_L("Associate files to OrcaSlicer"), page, _L("Associate files to OrcaSlicer"));
|
auto title_associate_file = create_item_title(_L("Associate files to OrcaSlicer"), page, _L("Associate files to OrcaSlicer"));
|
||||||
|
auto title_associate_url = create_item_title(_L("Associate web links to OrcaSlicer"), page, _L("Associate URLs to OrcaSlicer"));
|
||||||
|
|
||||||
// associate file
|
// associate file
|
||||||
auto item_associate_3mf = create_item_checkbox(_L("Associate .3mf files to OrcaSlicer"), page,
|
auto item_associate_3mf = create_item_checkbox(_L("Associate .3mf files to OrcaSlicer"), page,
|
||||||
|
@ -1076,12 +1082,18 @@ wxWindow* PreferencesDialog::create_general_page()
|
||||||
auto associate_url_prusaslicer = create_item_button(_L("Current association: ") + reg_bin, _L("Associate prusaslicer://"), page,
|
auto associate_url_prusaslicer = create_item_button(_L("Current association: ") + reg_bin, _L("Associate prusaslicer://"), page,
|
||||||
reg_bin.empty() ? _L("Not associated to any application") : reg_bin,
|
reg_bin.empty() ? _L("Not associated to any application") : reg_bin,
|
||||||
_L("Associate OrcaSlicer with prusaslicer:// links so that Orca can open models from Printable.com"),
|
_L("Associate OrcaSlicer with prusaslicer:// links so that Orca can open models from Printable.com"),
|
||||||
[]() { wxGetApp().associate_url(L"prusaslicer"); });
|
[]() { wxGetApp().associate_url(L"prusaslicer"); }, false);
|
||||||
wxGetApp().check_url_association(L"bambustudio", reg_bin);
|
wxGetApp().check_url_association(L"bambustudio", reg_bin);
|
||||||
auto associate_url_bambustudio = create_item_button(_L("Current association: ") + reg_bin, _L("Associate bambustudio://"), page,
|
auto associate_url_bambustudio = create_item_button(_L("Current association: ") + reg_bin, _L("Associate bambustudio://"), page,
|
||||||
reg_bin.empty() ? _L("Not associated to any application") : reg_bin,
|
reg_bin.empty() ? _L("Not associated to any application") : reg_bin,
|
||||||
_L("Associate OrcaSlicer with bambustudio:// links so that Orca can open models from makerworld.com"),
|
_L("Associate OrcaSlicer with bambustudio:// links so that Orca can open models from makerworld.com"),
|
||||||
[]() { wxGetApp().associate_url(L"bambustudio"); });
|
[]() { wxGetApp().associate_url(L"bambustudio"); }, false);
|
||||||
|
|
||||||
|
wxGetApp().check_url_association(L"cura", reg_bin);
|
||||||
|
auto associate_url_cura = create_item_button(_L("Current association: ") + reg_bin, _L("Associate cura://"), page,
|
||||||
|
reg_bin.empty() ? _L("Not associated to any application") : reg_bin,
|
||||||
|
_L("Associate OrcaSlicer with cura:// links so that Orca can open models from thingiverse.com"),
|
||||||
|
[]() { wxGetApp().associate_url(L"cura"); }, false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// auto title_modelmall = create_item_title(_L("Online Models"), page, _L("Online Models"));
|
// auto title_modelmall = create_item_title(_L("Online Models"), page, _L("Online Models"));
|
||||||
|
@ -1147,8 +1159,10 @@ wxWindow* PreferencesDialog::create_general_page()
|
||||||
sizer_page->Add(item_associate_step, 0, wxTOP, FromDIP(3));
|
sizer_page->Add(item_associate_step, 0, wxTOP, FromDIP(3));
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
#if !defined(__APPLE__)
|
#if !defined(__APPLE__)
|
||||||
sizer_page->Add(associate_url_prusaslicer, 0, wxTOP | wxEXPAND, FromDIP(20));
|
sizer_page->Add(title_associate_url, 0, wxTOP| wxEXPAND, FromDIP(20));
|
||||||
sizer_page->Add(associate_url_bambustudio, 0, wxTOP | wxEXPAND, FromDIP(20));
|
sizer_page->Add(associate_url_prusaslicer, 0, wxTOP, FromDIP(3));
|
||||||
|
sizer_page->Add(associate_url_bambustudio, 0, wxTOP, FromDIP(3));
|
||||||
|
sizer_page->Add(associate_url_cura, 0, wxTOP, FromDIP(3));
|
||||||
#endif
|
#endif
|
||||||
// auto item_title_modelmall = sizer_page->Add(title_modelmall, 0, wxTOP | wxEXPAND, FromDIP(20));
|
// auto item_title_modelmall = sizer_page->Add(title_modelmall, 0, wxTOP | wxEXPAND, FromDIP(20));
|
||||||
// auto item_item_modelmall = sizer_page->Add(item_modelmall, 0, wxTOP, FromDIP(3));
|
// auto item_item_modelmall = sizer_page->Add(item_modelmall, 0, wxTOP, FromDIP(3));
|
||||||
|
|
|
@ -111,7 +111,7 @@ public:
|
||||||
wxBoxSizer *create_item_checkbox(wxString title, wxWindow *parent, wxString tooltip, int padding_left, std::string param);
|
wxBoxSizer *create_item_checkbox(wxString title, wxWindow *parent, wxString tooltip, int padding_left, std::string param);
|
||||||
wxBoxSizer *create_item_darkmode_checkbox(wxString title, wxWindow *parent, wxString tooltip, int padding_left, std::string param);
|
wxBoxSizer *create_item_darkmode_checkbox(wxString title, wxWindow *parent, wxString tooltip, int padding_left, std::string param);
|
||||||
void set_dark_mode();
|
void set_dark_mode();
|
||||||
wxBoxSizer *create_item_button(wxString title, wxString title2, wxWindow *parent, wxString tooltip, wxString tooltip2, std::function<void()> onclick);
|
wxBoxSizer *create_item_button(wxString title, wxString title2, wxWindow *parent, wxString tooltip, wxString tooltip2, std::function<void()> onclick, bool button_on_left = false);
|
||||||
wxWindow* create_item_downloads(wxWindow* parent, int padding_left, std::string param);
|
wxWindow* create_item_downloads(wxWindow* parent, int padding_left, std::string param);
|
||||||
wxBoxSizer *create_item_input(wxString title, wxString title2, wxWindow *parent, wxString tooltip, std::string param, std::function<void(wxString)> onchange = {});
|
wxBoxSizer *create_item_input(wxString title, wxString title2, wxWindow *parent, wxString tooltip, std::string param, std::function<void(wxString)> onchange = {});
|
||||||
wxBoxSizer *create_item_backup_input(wxString title, wxWindow *parent, wxString tooltip, std::string param);
|
wxBoxSizer *create_item_backup_input(wxString title, wxWindow *parent, wxString tooltip, std::string param);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue