Fixed conflicts after merge with master

This commit is contained in:
enricoturri1966 2020-09-08 15:38:35 +02:00
commit 8cb2636afc
19 changed files with 297 additions and 81 deletions

View file

@ -106,9 +106,9 @@ if (MINGW)
set_target_properties(PrusaSlicer PROPERTIES PREFIX "")
endif (MINGW)
if (NOT WIN32)
# Binary name on unix like systems (OSX, Linux)
set_target_properties(PrusaSlicer PROPERTIES OUTPUT_NAME "prusa-slicer")
if (NOT WIN32 AND NOT APPLE)
# Binary name on unix like systems (Linux, Unix)
set_target_properties(PrusaSlicer PROPERTIES OUTPUT_NAME "prusa-slicer")
endif ()
target_link_libraries(PrusaSlicer libslic3r cereal)
@ -209,20 +209,34 @@ if (WIN32)
add_custom_target(PrusaSlicerDllsCopy ALL DEPENDS PrusaSlicer)
prusaslicer_copy_dlls(PrusaSlicerDllsCopy)
elseif (XCODE)
# Because of Debug/Release/etc. configurations (similar to MSVC) the slic3r binary is located in an extra level
add_custom_command(TARGET PrusaSlicer POST_BUILD
COMMAND ln -sfn "${SLIC3R_RESOURCES_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/resources"
COMMENT "Symlinking the resources directory into the build tree"
VERBATIM
)
else ()
if (APPLE)
# On OSX, the name of the binary matches the name of the Application.
add_custom_command(TARGET PrusaSlicer POST_BUILD
COMMAND ln -sf PrusaSlicer prusa-slicer
COMMAND ln -sf PrusaSlicer prusa-gcodeviewer
COMMAND ln -sf PrusaSlicer PrusaGCodeViewer
WORKING_DIRECTORY "$<TARGET_FILE_DIR:PrusaSlicer>"
COMMENT "Symlinking the G-code viewer to PrusaSlicer, symlinking to prusa-slicer and prusa-gcodeviewer"
VERBATIM)
else ()
add_custom_command(TARGET PrusaSlicer POST_BUILD
COMMAND ln -sf prusa-slicer prusa-gcodeviewer
WORKING_DIRECTORY "$<TARGET_FILE_DIR:PrusaSlicer>"
COMMENT "Symlinking the G-code viewer to PrusaSlicer"
VERBATIM)
endif ()
if (XCODE)
# Because of Debug/Release/etc. configurations (similar to MSVC) the slic3r binary is located in an extra level
set(BIN_RESOURCES_DIR "${CMAKE_CURRENT_BINARY_DIR}/resources")
else ()
set(BIN_RESOURCES_DIR "${CMAKE_CURRENT_BINARY_DIR}/../resources")
endif ()
add_custom_command(TARGET PrusaSlicer POST_BUILD
COMMAND ln -sfn "${SLIC3R_RESOURCES_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/../resources"
COMMAND ln -sfn "${SLIC3R_RESOURCES_DIR}" "${BIN_RESOURCES_DIR}"
COMMENT "Symlinking the resources directory into the build tree"
VERBATIM
)
endif()
VERBATIM)
endif ()
# Slic3r binary install target
if (WIN32)

View file

@ -22,6 +22,7 @@
#include <cstring>
#include <iostream>
#include <math.h>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem.hpp>
#include <boost/nowide/args.hpp>
#include <boost/nowide/cenv.hpp>
@ -101,8 +102,14 @@ int CLI::run(int argc, char **argv)
std::find(m_transforms.begin(), m_transforms.end(), "cut") == m_transforms.end() &&
std::find(m_transforms.begin(), m_transforms.end(), "cut_x") == m_transforms.end() &&
std::find(m_transforms.begin(), m_transforms.end(), "cut_y") == m_transforms.end();
bool start_as_gcodeviewer = false;
bool start_as_gcodeviewer =
#ifdef _WIN32
false;
#else
// On Unix systems, the prusa-slicer binary may be symlinked to give the application a different meaning.
boost::algorithm::iends_with(boost::filesystem::path(argv[0]).filename().string(), "gcodeviewer");
#endif // _WIN32
const std::vector<std::string> &load_configs = m_config.option<ConfigOptionStrings>("load", true)->values;
// load config files supplied via --load

View file

@ -1365,9 +1365,10 @@ const std::vector<std::string>& PhysicalPrinter::printer_options()
"print_host",
"printhost_apikey",
"printhost_cafile",
"authorization_type",
"login",
"password"
"printhost_authorization_type",
// HTTP digest authentization (RFC 2617)
"printhost_user",
"printhost_password"
};
}
return s_opts;
@ -1412,11 +1413,11 @@ const std::set<std::string>& PhysicalPrinter::get_preset_names() const
bool PhysicalPrinter::has_empty_config() const
{
return config.opt_string("print_host" ).empty() &&
config.opt_string("printhost_apikey").empty() &&
config.opt_string("printhost_cafile").empty() &&
config.opt_string("login" ).empty() &&
config.opt_string("password" ).empty();
return config.opt_string("print_host" ).empty() &&
config.opt_string("printhost_apikey" ).empty() &&
config.opt_string("printhost_cafile" ).empty() &&
config.opt_string("printhost_user" ).empty() &&
config.opt_string("printhost_password").empty();
}
void PhysicalPrinter::update_preset_names_in_config()
@ -1441,7 +1442,7 @@ void PhysicalPrinter::save(const std::string& file_name_from, const std::string&
void PhysicalPrinter::update_from_preset(const Preset& preset)
{
config.apply_only(preset.config, printer_options(), false);
config.apply_only(preset.config, printer_options(), true);
// add preset names to the options list
auto ret = preset_names.emplace(preset.name);
update_preset_names_in_config();
@ -1476,8 +1477,8 @@ bool PhysicalPrinter::delete_preset(const std::string& preset_name)
return preset_names.erase(preset_name) > 0;
}
PhysicalPrinter::PhysicalPrinter(const std::string& name, const Preset& preset) :
name(name)
PhysicalPrinter::PhysicalPrinter(const std::string& name, const DynamicPrintConfig &default_config, const Preset& preset) :
name(name), config(default_config)
{
update_from_preset(preset);
}
@ -1514,6 +1515,13 @@ std::string PhysicalPrinter::get_preset_name(std::string name)
PhysicalPrinterCollection::PhysicalPrinterCollection( const std::vector<std::string>& keys)
{
// Default config for a physical printer containing all key/value pairs of PhysicalPrinter::printer_options().
for (const std::string &key : keys) {
const ConfigOptionDef *opt = print_config_def.get(key);
assert(opt);
assert(opt->default_value);
m_default_config.set_key_value(key, opt->default_value->clone());
}
}
// Load all printers found in dir_path.
@ -1539,7 +1547,7 @@ void PhysicalPrinterCollection::load_printers(const std::string& dir_path, const
continue;
}
try {
PhysicalPrinter printer(name);
PhysicalPrinter printer(name, this->default_config());
printer.file = dir_entry.path().string();
// Load the preset file, apply preset values on top of defaults.
try {
@ -1590,7 +1598,7 @@ void PhysicalPrinterCollection::load_printers_from_presets(PrinterPresetCollecti
new_printer_name = (boost::format("Printer %1%") % ++cnt).str();
// create new printer from this preset
PhysicalPrinter printer(new_printer_name, preset);
PhysicalPrinter printer(new_printer_name, this->default_config(), preset);
printer.loaded = true;
save_printer(printer);
}

View file

@ -460,8 +460,7 @@ private:
// If a preset does not exist, an iterator is returned indicating where to insert a preset with the same name.
std::deque<Preset>::iterator find_preset_internal(const std::string &name)
{
Preset key(m_type, name);
auto it = std::lower_bound(m_presets.begin() + m_num_default_presets, m_presets.end(), key);
auto it = Slic3r::lower_bound_by_predicate(m_presets.begin() + m_num_default_presets, m_presets.end(), [&name](const auto& l) { return l.name < name; });
if (it == m_presets.end() || it->name != name) {
// Preset has not been not found in the sorted list of non-default presets. Try the defaults.
for (size_t i = 0; i < m_num_default_presets; ++ i)
@ -539,9 +538,8 @@ namespace PresetUtils {
class PhysicalPrinter
{
public:
PhysicalPrinter() {}
PhysicalPrinter(const std::string& name) : name(name){}
PhysicalPrinter(const std::string& name, const Preset& preset);
PhysicalPrinter(const std::string& name, const DynamicPrintConfig &default_config) : name(name), config(default_config) {}
PhysicalPrinter(const std::string& name, const DynamicPrintConfig &default_config, const Preset& preset);
void set_name(const std::string &name);
// Name of the Physical Printer, usually derived form the file name.
@ -698,6 +696,8 @@ public:
// Generate a file path from a profile name. Add the ".ini" suffix if it is missing.
std::string path_from_name(const std::string& new_name) const;
const DynamicPrintConfig& default_config() const { return m_default_config; }
private:
PhysicalPrinterCollection& operator=(const PhysicalPrinterCollection& other);
@ -707,9 +707,7 @@ private:
// If a preset does not exist, an iterator is returned indicating where to insert a preset with the same name.
std::deque<PhysicalPrinter>::iterator find_printer_internal(const std::string& name)
{
PhysicalPrinter printer(name);
auto it = std::lower_bound(m_printers.begin(), m_printers.end(), printer);
return it;
return Slic3r::lower_bound_by_predicate(m_printers.begin(), m_printers.end(), [&name](const auto& l) { return l.name < name; });
}
std::deque<PhysicalPrinter>::const_iterator find_printer_internal(const std::string& name) const
{
@ -723,6 +721,9 @@ private:
// so that the addresses of the presets don't change during resizing of the container.
std::deque<PhysicalPrinter> m_printers;
// Default config for a physical printer containing all key/value pairs of PhysicalPrinter::printer_options().
DynamicPrintConfig m_default_config;
// Selected printer.
size_t m_idx_selected = size_t(-1);
// The name of the preset which is currently select for this printer

View file

@ -133,13 +133,13 @@ void PrintConfigDef::init_common_params()
// Options used by physical printers
def = this->add("login", coString);
def->label = L("Login");
def = this->add("printhost_user", coString);
def->label = L("User");
// def->tooltip = L("");
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionString(""));
def = this->add("password", coString);
def = this->add("printhost_password", coString);
def->label = L("Password");
// def->tooltip = L("");
def->mode = comAdvanced;
@ -151,7 +151,7 @@ void PrintConfigDef::init_common_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionString(""));
def = this->add("authorization_type", coEnum);
def = this->add("printhost_authorization_type", coEnum);
def->label = L("Authorization Type");
// def->tooltip = L("");
def->enum_keys_map = &ConfigOptionEnum<AuthorizationType>::get_enum_values();

View file

@ -195,6 +195,8 @@ set(SLIC3R_GUI_SOURCES
Utils/Bonjour.hpp
Utils/PresetUpdater.cpp
Utils/PresetUpdater.hpp
Utils/Process.cpp
Utils/Process.hpp
Utils/Profile.hpp
Utils/UndoRedo.cpp
Utils/UndoRedo.hpp

View file

@ -1080,7 +1080,7 @@ boost::any& Choice::get_value()
m_value = static_cast<SLADisplayOrientation>(ret_enum);
else if (m_opt_id.compare("support_pillar_connection_mode") == 0)
m_value = static_cast<SLAPillarConnectionMode>(ret_enum);
else if (m_opt_id == "authorization_type")
else if (m_opt_id == "printhost_authorization_type")
m_value = static_cast<AuthorizationType>(ret_enum);
}
else if (m_opt.gui_type == "f_enum_open") {

View file

@ -194,7 +194,7 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
config.set_key_value(opt_key, new ConfigOptionEnum<SLADisplayOrientation>(boost::any_cast<SLADisplayOrientation>(value)));
else if(opt_key.compare("support_pillar_connection_mode") == 0)
config.set_key_value(opt_key, new ConfigOptionEnum<SLAPillarConnectionMode>(boost::any_cast<SLAPillarConnectionMode>(value)));
else if(opt_key == "authorization_type")
else if(opt_key == "printhost_authorization_type")
config.set_key_value(opt_key, new ConfigOptionEnum<AuthorizationType>(boost::any_cast<AuthorizationType>(value)));
}
break;

View file

@ -9,7 +9,6 @@
#include <wx/tooltip.h>
//#include <wx/glcanvas.h>
#include <wx/filename.h>
#include <wx/stdpaths.h>
#include <wx/debug.h>
#include <boost/algorithm/string/predicate.hpp>
@ -31,6 +30,7 @@
#include "I18N.hpp"
#include "GLCanvas3D.hpp"
#include "Plater.hpp"
#include "../Utils/Process.hpp"
#include <fstream>
#include "GUI_App.hpp"
@ -40,12 +40,6 @@
#include <shlobj.h>
#endif // _WIN32
// For starting another PrusaSlicer instance on OSX.
// Fails to compile on Windows on the build server.
#ifdef __APPLE__
#include <boost/process/spawn.hpp>
#endif
namespace Slic3r {
namespace GUI {
@ -1098,9 +1092,9 @@ void MainFrame::init_menubar()
append_menu_item(fileMenu, wxID_ANY, _L("&Repair STL file") + dots, _L("Automatically repair an STL file"),
[this](wxCommandEvent&) { repair_stl(); }, "wrench", nullptr,
[this]() { return true; }, this);
fileMenu->AppendSeparator();
#if ENABLE_GCODE_VIEWER
#if !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION
fileMenu->AppendSeparator();
append_menu_item(fileMenu, wxID_ANY, _L("&G-code preview"), _L("Switch to G-code preview mode"),
[this](wxCommandEvent&) {
if (m_plater->model().objects.empty() ||
@ -1110,6 +1104,8 @@ void MainFrame::init_menubar()
}, "", nullptr);
#endif // !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION
#endif // ENABLE_GCODE_VIEWER
append_menu_item(fileMenu, wxID_ANY, _L("&G-code preview") + dots, _L("Open G-code viewer"),
[this](wxCommandEvent&) { start_new_gcodeviewer_open_file(this); }, "", nullptr);
fileMenu->AppendSeparator();
append_menu_item(fileMenu, wxID_EXIT, _L("&Quit"), wxString::Format(_L("Quit %s"), SLIC3R_APP_NAME),
[this](wxCommandEvent&) { Close(false); });
@ -1226,20 +1222,11 @@ void MainFrame::init_menubar()
windowMenu->AppendSeparator();
append_menu_item(windowMenu, wxID_ANY, _L("Print &Host Upload Queue") + "\tCtrl+J", _L("Display the Print Host Upload Queue window"),
[this](wxCommandEvent&) { m_printhost_queue_dlg->Show(); }, "upload_queue", nullptr,
[this]() {return true; }, this);
[this](wxCommandEvent&) { m_printhost_queue_dlg->Show(); }, "upload_queue", nullptr, [this]() {return true; }, this);
windowMenu->AppendSeparator();
append_menu_item(windowMenu, wxID_ANY, _(L("Open new instance")) + "\tCtrl+I", _(L("Open a new PrusaSlicer instance")),
[this](wxCommandEvent&) {
wxString path = wxStandardPaths::Get().GetExecutablePath();
#ifdef __APPLE__
boost::process::spawn((const char*)path.c_str());
#else
wxExecute(wxStandardPaths::Get().GetExecutablePath(), wxEXEC_ASYNC | wxEXEC_HIDE_CONSOLE | wxEXEC_MAKE_GROUP_LEADER);
#endif
}, "upload_queue", nullptr,
[this]() {return true; }, this);
[this](wxCommandEvent&) { start_new_slicer(); }, "", nullptr);
}
// View menu

View file

@ -755,7 +755,7 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
else if (opt_key == "support_pillar_connection_mode") {
ret = static_cast<int>(config.option<ConfigOptionEnum<SLAPillarConnectionMode>>(opt_key)->value);
}
else if (opt_key == "authorization_type") {
else if (opt_key == "printhost_authorization_type") {
ret = static_cast<int>(config.option<ConfigOptionEnum<AuthorizationType>>(opt_key)->value);
}
}

View file

@ -155,8 +155,9 @@ void PresetForPrinter::msw_rescale()
// PhysicalPrinterDialog
//------------------------------------------
PhysicalPrinterDialog::PhysicalPrinterDialog(wxString printer_name)
: DPIDialog(NULL, wxID_ANY, _L("Physical Printer"), wxDefaultPosition, wxSize(45 * wxGetApp().em_unit(), -1), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
PhysicalPrinterDialog::PhysicalPrinterDialog(wxString printer_name) :
DPIDialog(NULL, wxID_ANY, _L("Physical Printer"), wxDefaultPosition, wxSize(45 * wxGetApp().em_unit(), -1), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
m_printer("", wxGetApp().preset_bundle->physical_printers.default_config())
{
SetFont(wxGetApp().normal_font());
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
@ -186,7 +187,8 @@ PhysicalPrinterDialog::PhysicalPrinterDialog(wxString printer_name)
PhysicalPrinter* printer = printers.find_printer(into_u8(printer_name));
if (!printer) {
const Preset& preset = wxGetApp().preset_bundle->printers.get_edited_preset();
printer = new PhysicalPrinter(into_u8(printer_name), preset);
//FIXME Vojtech: WTF??? Memory leak?
printer = new PhysicalPrinter(into_u8(printer_name), m_printer.config, preset);
// if printer_name is empty it means that new printer is created, so enable all items in the preset list
m_presets.emplace_back(new PresetForPrinter(this, preset.name));
}
@ -249,7 +251,7 @@ PhysicalPrinterDialog::~PhysicalPrinterDialog()
void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgroup)
{
m_optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) {
if (opt_key == "authorization_type")
if (opt_key == "printhost_authorization_type")
this->update();
};
@ -308,7 +310,7 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr
host_line.append_widget(print_host_test);
m_optgroup->append_line(host_line);
m_optgroup->append_single_option_line("authorization_type");
m_optgroup->append_single_option_line("printhost_authorization_type");
option = m_optgroup->get_option("printhost_apikey");
option.opt.width = Field::def_width_wider();
@ -368,7 +370,7 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr
m_optgroup->append_line(line);
}
for (const std::string& opt_key : std::vector<std::string>{ "login", "password" }) {
for (const std::string& opt_key : std::vector<std::string>{ "printhost_user", "printhost_password" }) {
option = m_optgroup->get_option(opt_key);
option.opt.width = Field::def_width_wider();
m_optgroup->append_single_option_line(option);
@ -385,20 +387,20 @@ void PhysicalPrinterDialog::update()
// Only offer the host type selection for FFF, for SLA it's always the SL1 printer (at the moment)
if (tech == ptFFF) {
m_optgroup->show_field("host_type");
m_optgroup->hide_field("authorization_type");
for (const std::string& opt_key : std::vector<std::string>{ "login", "password" })
m_optgroup->hide_field("printhost_authorization_type");
for (const std::string& opt_key : std::vector<std::string>{ "printhost_user", "printhost_password" })
m_optgroup->hide_field(opt_key);
}
else {
m_optgroup->set_value("host_type", int(PrintHostType::htOctoPrint), false);
m_optgroup->hide_field("host_type");
m_optgroup->show_field("authorization_type");
m_optgroup->show_field("printhost_authorization_type");
AuthorizationType auth_type = m_config->option<ConfigOptionEnum<AuthorizationType>>("authorization_type")->value;
AuthorizationType auth_type = m_config->option<ConfigOptionEnum<AuthorizationType>>("printhost_authorization_type")->value;
m_optgroup->show_field("printhost_apikey", auth_type == AuthorizationType::atKeyPassword);
for (const std::string& opt_key : std::vector<std::string>{ "login", "password" })
for (const std::string& opt_key : std::vector<std::string>{ "printhost_user", "printhost_password" })
m_optgroup->show_field(opt_key, auth_type == AuthorizationType::atUserPassword);
}

View file

@ -2835,7 +2835,7 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool
if (this->preview != nullptr) {
// If the preview is not visible, the following line just invalidates the preview,
// but the G-code paths or SLA preview are calculated first once the preview is made visible.
this->preview->get_canvas3d()->reset_gcode_toolpaths();
reset_gcode_toolpaths();
this->preview->reload_print();
}
#else
@ -5408,7 +5408,8 @@ void Plater::on_config_change(const DynamicPrintConfig &config)
this->set_printer_technology(config.opt_enum<PrinterTechnology>(opt_key));
// print technology is changed, so we should to update a search list
p->sidebar->update_searcher();
}
p->reset_gcode_toolpaths();
}
else if ((opt_key == "bed_shape") || (opt_key == "bed_custom_texture") || (opt_key == "bed_custom_model")) {
bed_shape_changed = true;
update_scheduled = true;

View file

@ -415,6 +415,16 @@ Http& Http::remove_header(std::string name)
return *this;
}
// Authorization by HTTP digest, based on RFC2617.
Http& Http::auth_digest(const std::string &user, const std::string &password)
{
curl_easy_setopt(p->curl, CURLOPT_USERNAME, user.c_str());
curl_easy_setopt(p->curl, CURLOPT_PASSWORD, password.c_str());
curl_easy_setopt(p->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
return *this;
}
Http& Http::ca_file(const std::string &name)
{
if (p && priv::ca_file_supported(p->curl)) {

View file

@ -64,6 +64,8 @@ public:
Http& header(std::string name, const std::string &value);
// Removes a header field.
Http& remove_header(std::string name);
// Authorization by HTTP digest, based on RFC2617.
Http& auth_digest(const std::string &user, const std::string &password);
// Sets a CA certificate file for usage with HTTPS. This is only supported on some backends,
// specifically, this is supported with OpenSSL and NOT supported with Windows and OS X native certificate store.
// See also ca_file_supported().

View file

@ -170,6 +170,13 @@ std::string OctoPrint::make_url(const std::string &path) const
}
}
SL1Host::SL1Host(DynamicPrintConfig *config) :
OctoPrint(config),
authorization_type(dynamic_cast<const ConfigOptionEnum<AuthorizationType>*>(config->option("printhost_authorization_type"))->value),
username(config->opt_string("printhost_user")),
password(config->opt_string("printhost_password"))
{
}
// SL1Host
const char* SL1Host::get_name() const { return "SL1Host"; }
@ -191,4 +198,20 @@ bool SL1Host::validate_version_text(const boost::optional<std::string> &version_
return version_text ? boost::starts_with(*version_text, "Prusa SLA") : false;
}
void SL1Host::set_auth(Http &http) const
{
switch (authorization_type) {
case atKeyPassword:
http.header("X-Api-Key", get_apikey());
break;
case atUserPassword:
http.auth_digest(username, password);
break;
}
if (! get_cafile().empty()) {
http.ca_file(get_cafile());
}
}
}

View file

@ -29,6 +29,8 @@ public:
bool can_test() const override { return true; }
bool can_start_print() const override { return true; }
std::string get_host() const override { return host; }
const std::string& get_apikey() const { return apikey; }
const std::string& get_cafile() const { return cafile; }
protected:
virtual bool validate_version_text(const boost::optional<std::string> &version_text) const;
@ -38,14 +40,14 @@ private:
std::string apikey;
std::string cafile;
void set_auth(Http &http) const;
virtual void set_auth(Http &http) const;
std::string make_url(const std::string &path) const;
};
class SL1Host: public OctoPrint
{
public:
SL1Host(DynamicPrintConfig *config) : OctoPrint(config) {}
SL1Host(DynamicPrintConfig *config);
~SL1Host() override = default;
const char* get_name() const override;
@ -56,6 +58,15 @@ public:
protected:
bool validate_version_text(const boost::optional<std::string> &version_text) const override;
private:
void set_auth(Http &http) const override;
// Host authorization type.
AuthorizationType authorization_type;
// username and password for HTTP Digest Authentization (RFC RFC2617)
std::string username;
std::string password;
};
}

View file

@ -0,0 +1,129 @@
#include "Process.hpp"
#include <libslic3r/AppConfig.hpp>
#include "../GUI/GUI.hpp"
// for file_wildcards()
#include "../GUI/GUI_App.hpp"
// localization
#include "../GUI/I18N.hpp"
#include <iostream>
#include <fstream>
#include <boost/filesystem.hpp>
#include <boost/log/trivial.hpp>
// For starting another PrusaSlicer instance on OSX.
// Fails to compile on Windows on the build server.
#ifdef __APPLE__
#include <boost/process/spawn.hpp>
#include <boost/process/args.hpp>
#endif
#include <wx/stdpaths.h>
namespace Slic3r {
namespace GUI {
enum class NewSlicerInstanceType {
Slicer,
GCodeViewer
};
// Start a new Slicer process instance either in a Slicer mode or in a G-code mode.
// Optionally load a 3MF, STL or a G-code on start.
static void start_new_slicer_or_gcodeviewer(const NewSlicerInstanceType instance_type, const wxString *path_to_open)
{
#ifdef _WIN32
wxString path;
wxFileName::SplitPath(wxStandardPaths::Get().GetExecutablePath(), &path, nullptr, nullptr, wxPATH_NATIVE);
path += "\\";
path += (instance_type == NewSlicerInstanceType::Slicer) ? "prusa-slicer.exe" : "prusa-gcodeviewer.exe";
std::vector<const wchar_t*> args;
args.reserve(3);
args.emplace_back(path.wc_str());
if (path_to_open != nullptr)
args.emplace_back(path_to_open->wc_str());
args.emplace_back(nullptr);
BOOST_LOG_TRIVIAL(info) << "Trying to spawn a new slicer \"" << into_u8(path) << "\"";
if (wxExecute(const_cast<wchar_t**>(args.data()), wxEXEC_ASYNC | wxEXEC_HIDE_CONSOLE | wxEXEC_MAKE_GROUP_LEADER) <= 0)
BOOST_LOG_TRIVIAL(error) << "Failed to spawn a new slicer \"" << into_u8(path);
#else
// Own executable path.
boost::filesystem::path bin_path = into_path(wxStandardPaths::Get().GetExecutablePath());
#if defined(__APPLE__)
{
bin_path = bin_path.parent_path() / ((instance_type == NewSlicerInstanceType::Slicer) ? "PrusaSlicer" : "PrusaGCodeViewer");
// On Apple the wxExecute fails, thus we use boost::process instead.
BOOST_LOG_TRIVIAL(info) << "Trying to spawn a new slicer \"" << bin_path.string() << "\"";
try {
std::vector<std::string> args;
if (path_to_open)
args.emplace_back(into_u8(*path_to_open));
boost::process::spawn(bin_path, args);
} catch (const std::exception &ex) {
BOOST_LOG_TRIVIAL(error) << "Failed to spawn a new slicer \"" << bin_path.string() << "\": " << ex.what();
}
}
#else // Linux or Unix
{
std::vector<const char*> args;
args.reserve(3);
#ifdef __linux
static const char *gcodeviewer_param = "--gcodeviewer";
{
// If executed by an AppImage, start the AppImage, not the main process.
// see https://docs.appimage.org/packaging-guide/environment-variables.html#id2
const char *appimage_binary = std::getenv("APPIMAGE");
if (appimage_binary) {
args.emplace_back(appimage_binary);
if (instance_type == NewSlicerInstanceType::GCodeViewer)
args.emplace_back(gcodeviewer_param);
}
}
#endif // __linux
std::string my_path;
if (args.empty()) {
// Binary path was not set to the AppImage in the Linux specific block above, call the application directly.
my_path = (bin_path.parent_path() / ((instance_type == NewSlicerInstanceType::Slicer) ? "prusa-slicer" : "prusa-gcodeviewer")).string();
args.emplace_back(my_path.c_str());
}
std::string to_open;
if (path_to_open) {
to_open = into_u8(*path_to_open);
args.emplace_back(to_open.c_str());
}
args.emplace_back(nullptr);
BOOST_LOG_TRIVIAL(info) << "Trying to spawn a new slicer \"" << args[0] << "\"";
if (wxExecute(const_cast<char**>(args.data()), wxEXEC_ASYNC | wxEXEC_HIDE_CONSOLE | wxEXEC_MAKE_GROUP_LEADER) <= 0)
BOOST_LOG_TRIVIAL(error) << "Failed to spawn a new slicer \"" << args[0];
}
#endif // Linux or Unix
#endif // Win32
}
void start_new_slicer(const wxString *path_to_open)
{
start_new_slicer_or_gcodeviewer(NewSlicerInstanceType::Slicer, path_to_open);
}
void start_new_gcodeviewer(const wxString *path_to_open)
{
start_new_slicer_or_gcodeviewer(NewSlicerInstanceType::GCodeViewer, path_to_open);
}
void start_new_gcodeviewer_open_file(wxWindow *parent)
{
wxFileDialog dialog(parent ? parent : wxGetApp().GetTopWindow(),
_L("Open G-code file:"),
from_u8(wxGetApp().app_config->get_last_dir()), wxString(),
file_wildcards(FT_GCODE), wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if (dialog.ShowModal() == wxID_OK) {
wxString path = dialog.GetPath();
start_new_gcodeviewer(&path);
}
}
} // namespace GUI
} // namespace Slic3r

View file

@ -0,0 +1,19 @@
#ifndef GUI_PROCESS_HPP
#define GUI_PROCESS_HPP
class wxWindow;
namespace Slic3r {
namespace GUI {
// Start a new slicer instance, optionally with a file to open.
void start_new_slicer(const wxString *path_to_open = nullptr);
// Start a new G-code viewer instance, optionally with a file to open.
void start_new_gcodeviewer(const wxString *path_to_open = nullptr);
// Open a file dialog, ask the user to select a new G-code to open, start a new G-code viewer.
void start_new_gcodeviewer_open_file(wxWindow *parent = nullptr);
} // namespace GUI
} // namespace Slic3r
#endif // GUI_PROCESS_HPP

View file

@ -1,5 +1,5 @@
#ifndef THREAD_HPP
#define THREAD_HPP
#ifndef GUI_THREAD_HPP
#define GUI_THREAD_HPP
#include <utility>
#include <boost/thread.hpp>
@ -25,4 +25,4 @@ template<class Fn> inline boost::thread create_thread(Fn &&fn)
}
#endif // THREAD_HPP
#endif // GUI_THREAD_HPP