Physical printers: Implemented import/export to/from the ConfigBundle.
+ fixed a bug : Case sensitivity of printer's name wasn't check during the adding of a new printer, as a result in printers list was appeared both of printers (ex. "YuSanka" and "yusanka"), but related file was just one.
This commit is contained in:
parent
94a9820661
commit
2bba0e3131
@ -1361,7 +1361,7 @@ const std::vector<std::string>& PhysicalPrinter::printer_options()
|
||||
s_opts = {
|
||||
"preset_name",
|
||||
"printer_technology",
|
||||
"printer_model",
|
||||
// "printer_model",
|
||||
"host_type",
|
||||
"print_host",
|
||||
"printhost_apikey",
|
||||
@ -1576,6 +1576,24 @@ void PhysicalPrinterCollection::load_printers(const std::string& dir_path, const
|
||||
throw Slic3r::RuntimeError(errors_cummulative);
|
||||
}
|
||||
|
||||
void PhysicalPrinterCollection::load_printer(const std::string& path, const std::string& name, DynamicPrintConfig&& config, bool select, bool save/* = false*/)
|
||||
{
|
||||
auto it = this->find_printer_internal(name);
|
||||
if (it == m_printers.end() || it->name != name) {
|
||||
// The preset was not found. Create a new preset.
|
||||
it = m_printers.emplace(it, PhysicalPrinter(name, config));
|
||||
}
|
||||
|
||||
it->file = path;
|
||||
it->config = std::move(config);
|
||||
it->loaded = true;
|
||||
if (select)
|
||||
this->select_printer(*it);
|
||||
|
||||
if (save)
|
||||
it->save();
|
||||
}
|
||||
|
||||
// if there is saved user presets, contains information about "Print Host upload",
|
||||
// Create default printers with this presets
|
||||
// Note! "Print Host upload" options will be cleared after physical printer creations
|
||||
@ -1623,12 +1641,39 @@ void PhysicalPrinterCollection::load_printers_from_presets(PrinterPresetCollecti
|
||||
}
|
||||
}
|
||||
|
||||
PhysicalPrinter* PhysicalPrinterCollection::find_printer( const std::string& name, bool first_visible_if_not_found)
|
||||
PhysicalPrinter* PhysicalPrinterCollection::find_printer( const std::string& name, bool case_sensitive_search)
|
||||
{
|
||||
auto it = this->find_printer_internal(name);
|
||||
auto it = this->find_printer_internal(name, case_sensitive_search);
|
||||
|
||||
// Ensure that a temporary copy is returned if the preset found is currently selected.
|
||||
return (it != m_printers.end() && it->name == name) ? &this->printer(it - m_printers.begin()) :
|
||||
first_visible_if_not_found ? &this->printer(0) : nullptr;
|
||||
auto is_equal_name = [name, case_sensitive_search](const std::string& in_name) {
|
||||
if (case_sensitive_search)
|
||||
return in_name == name;
|
||||
return boost::to_lower_copy<std::string>(in_name) == boost::to_lower_copy<std::string>(name);
|
||||
};
|
||||
|
||||
if (it == m_printers.end() || !is_equal_name(it->name))
|
||||
return nullptr;
|
||||
return &this->printer(it - m_printers.begin());
|
||||
}
|
||||
|
||||
std::deque<PhysicalPrinter>::iterator PhysicalPrinterCollection::find_printer_internal(const std::string& name, bool case_sensitive_search/* = true*/)
|
||||
{
|
||||
if (case_sensitive_search)
|
||||
return Slic3r::lower_bound_by_predicate(m_printers.begin(), m_printers.end(), [&name](const auto& l) { return l.name < name; });
|
||||
|
||||
std::string low_name = boost::to_lower_copy<std::string>(name);
|
||||
|
||||
int i = 0;
|
||||
for (const PhysicalPrinter& printer : m_printers) {
|
||||
if (boost::to_lower_copy<std::string>(printer.name) == low_name)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
if (i == m_printers.size())
|
||||
return m_printers.end();
|
||||
|
||||
return m_printers.begin() + i;
|
||||
}
|
||||
|
||||
PhysicalPrinter* PhysicalPrinterCollection::find_printer_with_same_config(const DynamicPrintConfig& config)
|
||||
@ -1667,10 +1712,13 @@ void PhysicalPrinterCollection::save_printer(PhysicalPrinter& edited_printer, co
|
||||
it->config = std::move(edited_printer.config);
|
||||
it->name = edited_printer.name;
|
||||
it->preset_names = edited_printer.preset_names;
|
||||
// sort printers and get new it
|
||||
std::sort(m_printers.begin(), m_printers.end());
|
||||
it = this->find_printer_internal(edited_printer.name);
|
||||
}
|
||||
else {
|
||||
// Creating a new printer.
|
||||
it = m_printers.insert(it, edited_printer);
|
||||
it = m_printers.emplace(it, edited_printer);
|
||||
}
|
||||
assert(it != m_printers.end());
|
||||
|
||||
|
@ -632,6 +632,8 @@ public:
|
||||
// Load ini files of the particular type from the provided directory path.
|
||||
void load_printers(const std::string& dir_path, const std::string& subdir);
|
||||
void load_printers_from_presets(PrinterPresetCollection &printer_presets);
|
||||
// Load printer from the loaded configuration
|
||||
void load_printer(const std::string& path, const std::string& name, DynamicPrintConfig&& config, bool select, bool save=false);
|
||||
|
||||
// Save the printer under a new name. If the name is different from the old one,
|
||||
// a new printer is stored into the list of printers.
|
||||
@ -687,10 +689,11 @@ public:
|
||||
|
||||
// Return a preset by its name. If the preset is active, a temporary copy is returned.
|
||||
// If a preset is not found by its name, null is returned.
|
||||
PhysicalPrinter* find_printer(const std::string& name, bool first_visible_if_not_found = false);
|
||||
const PhysicalPrinter* find_printer(const std::string& name, bool first_visible_if_not_found = false) const
|
||||
// It is possible case (in)sensitive search
|
||||
PhysicalPrinter* find_printer(const std::string& name, bool case_sensitive_search = true);
|
||||
const PhysicalPrinter* find_printer(const std::string& name, bool case_sensitive_search = true) const
|
||||
{
|
||||
return const_cast<PhysicalPrinterCollection*>(this)->find_printer(name, first_visible_if_not_found);
|
||||
return const_cast<PhysicalPrinterCollection*>(this)->find_printer(name, case_sensitive_search);
|
||||
}
|
||||
|
||||
// Generate a file path from a profile name. Add the ".ini" suffix if it is missing.
|
||||
@ -701,15 +704,11 @@ public:
|
||||
private:
|
||||
PhysicalPrinterCollection& operator=(const PhysicalPrinterCollection& other);
|
||||
|
||||
// Find a preset position in the sorted list of presets.
|
||||
// The "-- default -- " preset is always the first, so it needs
|
||||
// to be handled differently.
|
||||
// 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)
|
||||
{
|
||||
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
|
||||
// Find a physical printer position in the sorted list of printers.
|
||||
// The name of a printer should be unique and case insensitive
|
||||
// Use this functions with case_sensitive_search = false, when you need case insensitive search
|
||||
std::deque<PhysicalPrinter>::iterator find_printer_internal(const std::string& name, bool case_sensitive_search = true);
|
||||
std::deque<PhysicalPrinter>::const_iterator find_printer_internal(const std::string& name, bool case_sensitive_search = true) const
|
||||
{
|
||||
return const_cast<PhysicalPrinterCollection*>(this)->find_printer_internal(name);
|
||||
}
|
||||
|
@ -1113,16 +1113,22 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
|
||||
std::vector<std::string> loaded_sla_prints;
|
||||
std::vector<std::string> loaded_sla_materials;
|
||||
std::vector<std::string> loaded_printers;
|
||||
std::vector<std::string> loaded_physical_printers;
|
||||
std::string active_print;
|
||||
std::vector<std::string> active_filaments;
|
||||
std::string active_sla_print;
|
||||
std::string active_sla_material;
|
||||
std::string active_printer;
|
||||
std::string active_physical_printer;
|
||||
size_t presets_loaded = 0;
|
||||
size_t ph_printers_loaded = 0;
|
||||
|
||||
for (const auto §ion : tree) {
|
||||
PresetCollection *presets = nullptr;
|
||||
std::vector<std::string> *loaded = nullptr;
|
||||
std::string preset_name;
|
||||
PhysicalPrinterCollection *ph_printers = nullptr;
|
||||
std::string ph_printer_name;
|
||||
if (boost::starts_with(section.first, "print:")) {
|
||||
presets = &this->prints;
|
||||
loaded = &loaded_prints;
|
||||
@ -1143,6 +1149,10 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
|
||||
presets = &this->printers;
|
||||
loaded = &loaded_printers;
|
||||
preset_name = section.first.substr(8);
|
||||
} else if (boost::starts_with(section.first, "physical_printer:")) {
|
||||
ph_printers = &this->physical_printers;
|
||||
loaded = &loaded_physical_printers;
|
||||
ph_printer_name = section.first.substr(17);
|
||||
} else if (section.first == "presets") {
|
||||
// Load the names of the active presets.
|
||||
for (auto &kvp : section.second) {
|
||||
@ -1161,6 +1171,8 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
|
||||
active_sla_material = kvp.second.data();
|
||||
} else if (kvp.first == "printer") {
|
||||
active_printer = kvp.second.data();
|
||||
}else if (kvp.first == "physical_printer") {
|
||||
active_physical_printer = kvp.second.data();
|
||||
}
|
||||
}
|
||||
} else if (section.first == "obsolete_presets") {
|
||||
@ -1317,9 +1329,46 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
|
||||
|
||||
++ presets_loaded;
|
||||
}
|
||||
|
||||
if (ph_printers != nullptr) {
|
||||
// Load the physical printer
|
||||
const DynamicPrintConfig& default_config = ph_printers->default_config();
|
||||
DynamicPrintConfig config = default_config;
|
||||
|
||||
for (auto& kvp : section.second)
|
||||
config.set_deserialize(kvp.first, kvp.second.data());
|
||||
|
||||
// Report configuration fields, which are misplaced into a wrong group.
|
||||
std::string incorrect_keys = Preset::remove_invalid_keys(config, default_config);
|
||||
if (!incorrect_keys.empty())
|
||||
BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The physical printer \"" <<
|
||||
section.first << "\" contains the following incorrect keys: " << incorrect_keys << ", which were removed";
|
||||
|
||||
const PhysicalPrinter* ph_printer_existing = ph_printers->find_printer(ph_printer_name, false);
|
||||
if (ph_printer_existing != nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The physical printer \"" <<
|
||||
section.first << "\" has already been loaded from another Confing Bundle.";
|
||||
continue;
|
||||
}
|
||||
|
||||
// 3) Activate the presets.
|
||||
// Decide a full path to this .ini file.
|
||||
auto file_name = boost::algorithm::iends_with(ph_printer_name, ".ini") ? ph_printer_name : ph_printer_name + ".ini";
|
||||
auto file_path = (boost::filesystem::path(data_dir())
|
||||
#ifdef SLIC3R_PROFILE_USE_PRESETS_SUBDIR
|
||||
// Store the physical printers into a "presets" directory.
|
||||
/ "presets"
|
||||
#else
|
||||
// Store the physical printers at the same location as the upstream Slic3r.
|
||||
#endif
|
||||
/ "physical_printer" / file_name).make_preferred();
|
||||
// Load the preset into the list of presets, save it to disk.
|
||||
ph_printers->load_printer(file_path.string(), ph_printer_name, std::move(config), false, flags & LOAD_CFGBNDLE_SAVE);
|
||||
|
||||
++ph_printers_loaded;
|
||||
}
|
||||
}
|
||||
|
||||
// 3) Activate the presets and physical printer if any exists.
|
||||
if ((flags & LOAD_CFGBNDLE_SYSTEM) == 0) {
|
||||
if (! active_print.empty())
|
||||
prints.select_preset_by_name(active_print, true);
|
||||
@ -1329,6 +1378,8 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
|
||||
sla_materials.select_preset_by_name(active_sla_material, true);
|
||||
if (! active_printer.empty())
|
||||
printers.select_preset_by_name(active_printer, true);
|
||||
if (! active_physical_printer.empty())
|
||||
physical_printers.select_printer(active_physical_printer +" * " + active_printer);
|
||||
// Activate the first filament preset.
|
||||
if (! active_filaments.empty() && ! active_filaments.front().empty())
|
||||
filaments.select_preset_by_name(active_filaments.front(), true);
|
||||
@ -1338,7 +1389,7 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
|
||||
this->update_compatible(PresetSelectCompatibleType::Never);
|
||||
}
|
||||
|
||||
return presets_loaded;
|
||||
return presets_loaded + ph_printers_loaded;
|
||||
}
|
||||
|
||||
void PresetBundle::update_multi_material_filament_presets()
|
||||
@ -1458,7 +1509,7 @@ void PresetBundle::update_compatible(PresetSelectCompatibleType select_other_pri
|
||||
}
|
||||
}
|
||||
|
||||
void PresetBundle::export_configbundle(const std::string &path, bool export_system_settings)
|
||||
void PresetBundle::export_configbundle(const std::string &path, bool export_system_settings, bool export_physical_printers/* = false*/)
|
||||
{
|
||||
boost::nowide::ofstream c;
|
||||
c.open(path, std::ios::out | std::ios::trunc);
|
||||
@ -1482,6 +1533,14 @@ void PresetBundle::export_configbundle(const std::string &path, bool export_syst
|
||||
}
|
||||
}
|
||||
|
||||
if (export_physical_printers) {
|
||||
for (const PhysicalPrinter& ph_printer : this->physical_printers) {
|
||||
c << std::endl << "[physical_printer:" << ph_printer.name << "]" << std::endl;
|
||||
for (const std::string& opt_key : ph_printer.config.keys())
|
||||
c << opt_key << " = " << ph_printer.config.opt_serialize(opt_key) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Export the names of the active presets.
|
||||
c << std::endl << "[presets]" << std::endl;
|
||||
c << "print = " << this->prints.get_selected_preset_name() << std::endl;
|
||||
@ -1497,6 +1556,8 @@ void PresetBundle::export_configbundle(const std::string &path, bool export_syst
|
||||
c << "filament" << suffix << " = " << this->filament_presets[i] << std::endl;
|
||||
}
|
||||
|
||||
if (export_physical_printers && this->physical_printers.get_selected_idx() >= 0)
|
||||
c << "physical_printer = " << this->physical_printers.get_selected_printer_name() << std::endl;
|
||||
#if 0
|
||||
// Export the following setting values from the provided setting repository.
|
||||
static const char *settings_keys[] = { "autocenter" };
|
||||
|
@ -102,7 +102,7 @@ public:
|
||||
size_t load_configbundle(const std::string &path, unsigned int flags = LOAD_CFGBNDLE_SAVE);
|
||||
|
||||
// Export a config bundle file containing all the presets and the names of the active presets.
|
||||
void export_configbundle(const std::string &path, bool export_system_settings = false);
|
||||
void export_configbundle(const std::string &path, bool export_system_settings = false, bool export_physical_printers = false);
|
||||
|
||||
// Enable / disable the "- default -" preset.
|
||||
void set_default_suppressed(bool default_suppressed);
|
||||
|
@ -1071,6 +1071,9 @@ void MainFrame::init_menubar()
|
||||
append_menu_item(export_menu, wxID_ANY, _L("Export Config &Bundle") + dots, _L("Export all presets to file"),
|
||||
[this](wxCommandEvent&) { export_configbundle(); }, "export_config_bundle", nullptr,
|
||||
[this]() {return true; }, this);
|
||||
append_menu_item(export_menu, wxID_ANY, _L("Export Config Bundle With Physical Printers") + dots, _L("Export all presets including physical printers to file"),
|
||||
[this](wxCommandEvent&) { export_configbundle(true); }, "export_config_bundle", nullptr,
|
||||
[this]() {return true; }, this);
|
||||
append_submenu(fileMenu, export_menu, wxID_ANY, _L("&Export"), "");
|
||||
|
||||
append_menu_item(fileMenu, wxID_ANY, _L("Ejec&t SD card / Flash drive") + dots + "\tCtrl+T", _L("Eject SD card / Flash drive after the G-code was exported to it."),
|
||||
@ -1641,7 +1644,7 @@ bool MainFrame::load_config_file(const std::string &path)
|
||||
return true;
|
||||
}
|
||||
|
||||
void MainFrame::export_configbundle()
|
||||
void MainFrame::export_configbundle(bool export_physical_printers /*= false*/)
|
||||
{
|
||||
if (!wxGetApp().check_unsaved_changes())
|
||||
return;
|
||||
@ -1663,7 +1666,7 @@ void MainFrame::export_configbundle()
|
||||
// Export the config bundle.
|
||||
wxGetApp().app_config->update_config_dir(get_dir_name(file));
|
||||
try {
|
||||
wxGetApp().preset_bundle->export_configbundle(file.ToUTF8().data());
|
||||
wxGetApp().preset_bundle->export_configbundle(file.ToUTF8().data(), false, export_physical_printers);
|
||||
} catch (const std::exception &ex) {
|
||||
show_error(this, ex.what());
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ public:
|
||||
void load_config_file();
|
||||
// Open a config file. Return true if loaded.
|
||||
bool load_config_file(const std::string &path);
|
||||
void export_configbundle();
|
||||
void export_configbundle(bool export_physical_printers = false);
|
||||
void load_configbundle(wxString file = wxEmptyString);
|
||||
void load_config(const DynamicPrintConfig& config);
|
||||
// Select tab in m_tabpanel
|
||||
|
@ -468,15 +468,17 @@ void PhysicalPrinterDialog::OnOK(wxEvent& event)
|
||||
}
|
||||
|
||||
PhysicalPrinterCollection& printers = wxGetApp().preset_bundle->physical_printers;
|
||||
const PhysicalPrinter* existing = printers.find_printer(into_u8(printer_name));
|
||||
const PhysicalPrinter* existing = printers.find_printer(into_u8(printer_name), false);
|
||||
if (existing && into_u8(printer_name) != printers.get_selected_printer_name())
|
||||
{
|
||||
wxString msg_text = from_u8((boost::format(_u8L("Printer with name \"%1%\" already exists.")) % printer_name).str());
|
||||
wxString msg_text = from_u8((boost::format(_u8L("Printer with name \"%1%\" already exists.")) % existing->name/*printer_name*/).str());
|
||||
msg_text += "\n" + _L("Replace?");
|
||||
wxMessageDialog dialog(nullptr, msg_text, _L("Warning"), wxICON_WARNING | wxYES | wxNO);
|
||||
|
||||
if (dialog.ShowModal() == wxID_NO)
|
||||
return;
|
||||
|
||||
m_printer.name = existing->name;
|
||||
}
|
||||
|
||||
std::set<std::string> repeat_presets;
|
||||
|
Loading…
Reference in New Issue
Block a user