Fixed conflicts after merge with master
This commit is contained in:
commit
8cb2636afc
19 changed files with 297 additions and 81 deletions
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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") {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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().
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
129
src/slic3r/Utils/Process.cpp
Normal file
129
src/slic3r/Utils/Process.cpp
Normal 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
|
19
src/slic3r/Utils/Process.hpp
Normal file
19
src/slic3r/Utils/Process.hpp
Normal 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
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue