Apply printer model / variant preferences when loading presets

This commit is contained in:
Vojtech Kral 2018-03-29 17:54:43 +02:00
parent 57e47a3296
commit e53949f2c8
17 changed files with 218 additions and 64 deletions

View file

@ -135,7 +135,7 @@ void AppConfig::save()
bool AppConfig::get_variant(const std::string &vendor, const std::string &model, const std::string &variant) const
{
std::cerr << "AppConfig::get_variant(" << vendor << ", " << model << ", " << variant << ") ";
// std::cerr << "AppConfig::get_variant(" << vendor << ", " << model << ", " << variant << ") " << std::endl;
const auto it_v = m_vendors.find(vendor);
if (it_v == m_vendors.end()) { return false; }
@ -161,6 +161,12 @@ void AppConfig::set_variant(const std::string &vendor, const std::string &model,
m_dirty = true;
}
void AppConfig::set_vendors(const AppConfig &from)
{
m_vendors = from.m_vendors;
m_dirty = true;
}
std::string AppConfig::get_last_dir() const
{
const auto it = m_storage.find("recent");

View file

@ -68,12 +68,9 @@ public:
void clear_section(const std::string &section)
{ m_storage[section].clear(); }
// TODO: remove / upgrade
// ConfigOptionStrings get_strings(const std::string &section, const std::string &key) const;
// void set_strings(const std::string &section, const std::string &key, const ConfigOptionStrings &value);
// TODO:
bool get_variant(const std::string &vendor, const std::string &model, const std::string &variant) const;
void set_variant(const std::string &vendor, const std::string &model, const std::string &variant, bool enable);
void set_vendors(const AppConfig &from);
// return recent/skein_directory or recent/config_directory or empty string.
std::string get_last_dir() const;

View file

@ -74,13 +74,17 @@ void ConfigWizardPage::append_text(wxString text)
auto *widget = new wxStaticText(this, wxID_ANY, text, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
widget->Wrap(CONTENT_WIDTH);
widget->SetMinSize(wxSize(CONTENT_WIDTH, -1));
// content->Add(widget, 1, wxALIGN_LEFT | wxTOP | wxBOTTOM, 10);
content->Add(widget, 0, wxALIGN_LEFT | wxTOP | wxBOTTOM, 10);
}
void ConfigWizardPage::append_widget(wxWindow *widget, int proportion)
void ConfigWizardPage::append_widget(wxWindow *widget, int proportion, int flag, int border)
{
content->Add(widget, proportion, wxEXPAND | wxTOP | wxBOTTOM, 10);
content->Add(widget, proportion, flag, border);
}
void ConfigWizardPage::append_sizer(wxSizer *sizer, int proportion)
{
content->Add(sizer, proportion, wxEXPAND | wxTOP | wxBOTTOM, 10);
}
void ConfigWizardPage::append_spacer(int space)
@ -99,17 +103,19 @@ void ConfigWizardPage::enable_next(bool enable) { parent->p->enable_next(enable)
// Wizard pages
PageWelcome::PageWelcome(ConfigWizard *parent, const PresetBundle &bundle) :
// PageWelcome::PageWelcome(ConfigWizard *parent, const PresetBundle &bundle) :
PageWelcome::PageWelcome(ConfigWizard *parent) :
ConfigWizardPage(parent, _(L("Welcome to the Slic3r Configuration assistant")), _(L("Welcome"))),
others_buttons(new wxPanel(parent)),
variants_checked(0)
{
append_text(_(L("Hello, welcome to Slic3r Prusa Edition! TODO: This text.")));
const PresetBundle &bundle = wizard_p()->bundle_vendors;
const auto &vendors = bundle.vendors;
const auto vendor_prusa = std::find(vendors.cbegin(), vendors.cend(), VendorProfile("PrusaResearch"));
// TODO: preload checkiness from app config
const AppConfig &appconfig_vendors = wizard_p()->appconfig_vendors;
if (vendor_prusa != vendors.cend()) {
const auto &models = vendor_prusa->models;
@ -138,12 +144,20 @@ PageWelcome::PageWelcome(ConfigWizard *parent, const PresetBundle &bundle) :
sizer->AddSpacer(20);
std::string model_id = model->id;
for (const auto &variant : model->variants) {
std::string variant_name = variant.name;
auto *cbox = new wxCheckBox(panel, wxID_ANY, wxString::Format("%s %s %s", variant.name, _(L("mm")), _(L("nozzle"))));
bool enabled = appconfig_vendors.get_variant("PrusaResearch", model_id, variant_name);
variants_checked += enabled;
cbox->SetValue(enabled);
sizer->Add(cbox, 0, wxBOTTOM, 3);
cbox->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent &event) {
cbox->Bind(wxEVT_CHECKBOX, [=](wxCommandEvent &event) {
this->variants_checked += event.IsChecked() ? 1 : -1;
this->on_variant_checked();
AppConfig &appconfig_vendors = this->wizard_p()->appconfig_vendors;
appconfig_vendors.set_variant("PrusaResearch", model_id, variant_name, event.IsChecked());
});
}
@ -156,6 +170,7 @@ PageWelcome::PageWelcome(ConfigWizard *parent, const PresetBundle &bundle) :
{
auto *sizer = new wxBoxSizer(wxHORIZONTAL);
auto *other_vendors = new wxButton(others_buttons, wxID_ANY, _(L("Other vendors")));
other_vendors->Disable();
auto *custom_setup = new wxButton(others_buttons, wxID_ANY, _(L("Custom setup")));
sizer->Add(other_vendors);
@ -181,17 +196,24 @@ void PageWelcome::on_variant_checked()
}
PageUpdate::PageUpdate(ConfigWizard *parent) :
ConfigWizardPage(parent, _(L("Automatic updates")), _(L("Updates")))
ConfigWizardPage(parent, _(L("Automatic updates")), _(L("Updates"))),
version_check(true),
preset_update(true)
{
append_text(_(L("TODO: text")));
auto *box_slic3r = new wxCheckBox(this, wxID_ANY, _(L("Check for Slic3r updates")));
box_slic3r->SetValue(true);
append_widget(box_slic3r);
const AppConfig *app_config = GUI::get_app_config();
append_text(_(L("TODO: text")));
auto *box_slic3r = new wxCheckBox(this, wxID_ANY, _(L("Check for Slic3r updates")));
box_slic3r->SetValue(app_config->get("version_check") == "1");
append_widget(box_slic3r);
append_text(_(L("TODO: text")));
auto *box_presets = new wxCheckBox(this, wxID_ANY, _(L("Update built-in Presets automatically")));
box_presets->SetValue(true);
box_presets->SetValue(app_config->get("preset_update") == "1");
append_widget(box_presets);
box_slic3r->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent &event) { this->version_check = event.IsChecked(); });
box_presets->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent &event) { this->preset_update = event.IsChecked(); });
}
void PageUpdate::presets_update_enable(bool enable)
@ -201,7 +223,42 @@ void PageUpdate::presets_update_enable(bool enable)
PageVendors::PageVendors(ConfigWizard *parent) :
ConfigWizardPage(parent, _(L("Other Vendors")), _(L("Other Vendors")))
{}
{
enum {
INDENT_SPACING = 30,
VERTICAL_SPACING = 10,
};
append_text(_(L("Other vendors! TODO: This text.")));
const PresetBundle &bundle = wizard_p()->bundle_vendors;
auto boldfont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
boldfont.SetWeight(wxFONTWEIGHT_BOLD);
for (const auto &vendor : bundle.vendors) {
if (vendor.id == "PrusaResearch") { continue; }
auto *label_vendor = new wxStaticText(this, wxID_ANY, vendor.name);
label_vendor->SetFont(boldfont);
append_thing(label_vendor, 0, 0, 0);
for (const auto &model : vendor.models) {
auto *label_model = new wxStaticText(this, wxID_ANY, model.name);
label_model->SetFont(boldfont);
append_thing(label_model, 0, wxLEFT, INDENT_SPACING);
for (const auto &variant : model.variants) {
auto *cbox = new wxCheckBox(this, wxID_ANY, variant.name);
append_thing(cbox, 0, wxEXPAND | wxLEFT, 2 * INDENT_SPACING);
cbox->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent &event) {
// TODO
});
}
}
append_spacer(VERTICAL_SPACING);
}
}
PageFirmware::PageFirmware(ConfigWizard *parent) :
ConfigWizardPage(parent, _(L("Firmware Type")), _(L("Firmware")))
@ -289,6 +346,31 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt)
// priv
void ConfigWizard::priv::load_vendors()
{
const auto vendor_dir = fs::path(Slic3r::data_dir()) / "vendor";
// const auto profiles_dir = fs::path(resources_dir()) / "profiles";
for (fs::directory_iterator it(vendor_dir); it != fs::directory_iterator(); ++it) {
if (it->path().extension() == ".ini") {
bundle_vendors.load_configbundle(it->path().native(), PresetBundle::LOAD_CFGBUNDLE_VENDOR_ONLY);
}
}
// XXX
// for (const auto &vendor : bundle_vendors.vendors) {
// std::cerr << "vendor: " << vendor.name << std::endl;
// std::cerr << " URL: " << vendor.config_update_url << std::endl;
// for (const auto &model : vendor.models) {
// std::cerr << "\tmodel: " << model.id << " (" << model.name << ")" << std::endl;
// for (const auto &variant : model.variants) {
// std::cerr << "\t\tvariant: " << variant.name << std::endl;
// }
// }
// }
appconfig_vendors.set_vendors(*GUI::get_app_config());
}
void ConfigWizard::priv::index_refresh()
{
index->load_items(page_welcome);
@ -344,12 +426,31 @@ void ConfigWizard::priv::on_custom_setup()
set_page(page_firmware);
}
void ConfigWizard::priv::on_finish()
{
const bool is_custom_setup = page_welcome->page_next() == page_firmware;
if (! is_custom_setup) {
AppConfig *app_config = GUI::get_app_config();
app_config->set_vendors(appconfig_vendors);
app_config->set("version_check", page_update->version_check ? "1" : "0");
app_config->set("preset_update", page_update->preset_update ? "1" : "0");
} else {
// TODO
}
q->EndModal(wxID_OK);
}
// Public
ConfigWizard::ConfigWizard(wxWindow *parent, const PresetBundle &bundle) :
ConfigWizard::ConfigWizard(wxWindow *parent) :
wxDialog(parent, wxID_ANY, _(L("Configuration Assistant")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
p(new priv(this))
{
p->load_vendors();
p->index = new ConfigWizardIndex(this);
auto *vsizer = new wxBoxSizer(wxVERTICAL);
@ -372,7 +473,7 @@ ConfigWizard::ConfigWizard(wxWindow *parent, const PresetBundle &bundle) :
p->btnsizer->Add(p->btn_finish, 0, wxLEFT, BTN_SPACING);
p->btnsizer->Add(p->btn_cancel, 0, wxLEFT, BTN_SPACING);
p->add_page(p->page_welcome = new PageWelcome(this, bundle));
p->add_page(p->page_welcome = new PageWelcome(this));
p->add_page(p->page_update = new PageUpdate(this));
p->add_page(p->page_vendors = new PageVendors(this));
p->add_page(p->page_firmware = new PageFirmware(this));
@ -397,35 +498,24 @@ ConfigWizard::ConfigWizard(wxWindow *parent, const PresetBundle &bundle) :
p->btn_prev->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &evt) { this->p->go_prev(); });
p->btn_next->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &evt) { this->p->go_next(); });
p->btn_finish->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &evt) { this->p->on_finish(); });
}
ConfigWizard::~ConfigWizard() {}
void ConfigWizard::run(wxWindow *parent)
void ConfigWizard::run(wxWindow *parent, PresetBundle *preset_bundle)
{
PresetBundle bundle;
const auto profiles_dir = fs::path(resources_dir()) / "profiles";
for (fs::directory_iterator it(profiles_dir); it != fs::directory_iterator(); ++it) {
if (it->path().extension() == ".ini") {
bundle.load_configbundle(it->path().native(), PresetBundle::LOAD_CFGBUNDLE_VENDOR_ONLY);
PresetBundle::install_vendor_configbundle(it->path());
}
}
// XXX
for (const auto &vendor : bundle.vendors) {
std::cerr << "vendor: " << vendor.name << std::endl;
std::cerr << " URL: " << vendor.config_update_url << std::endl;
for (const auto &model : vendor.models) {
std::cerr << "\tmodel: " << model.id << " (" << model.name << ")" << std::endl;
for (const auto &variant : model.variants) {
std::cerr << "\t\tvariant: " << variant.name << std::endl;
}
}
ConfigWizard wizard(parent);
if (wizard.ShowModal() == wxID_OK) {
preset_bundle->load_presets(*GUI::get_app_config());
}
ConfigWizard wizard(parent, bundle);
wizard.ShowModal();
}

View file

@ -15,14 +15,15 @@ namespace GUI {
class ConfigWizard: public wxDialog
{
public:
ConfigWizard(wxWindow *parent, const PresetBundle &bundle);
// ConfigWizard(wxWindow *parent, const PresetBundle &bundle);
ConfigWizard(wxWindow *parent);
ConfigWizard(ConfigWizard &&) = delete;
ConfigWizard(const ConfigWizard &) = delete;
ConfigWizard &operator=(ConfigWizard &&) = delete;
ConfigWizard &operator=(const ConfigWizard &) = delete;
~ConfigWizard();
static void run(wxWindow *parent);
static void run(wxWindow *parent, PresetBundle *preset_bundle);
private:
struct priv;
std::unique_ptr<priv> p;

View file

@ -9,6 +9,9 @@
#include <wx/panel.h>
#include <wx/button.h>
#include "AppConfig.hpp"
#include "PresetBundle.hpp"
namespace Slic3r {
namespace GUI {
@ -34,14 +37,23 @@ struct ConfigWizardPage: wxPanel
virtual ~ConfigWizardPage();
ConfigWizardPage *page_prev() const { return p_prev; }
ConfigWizardPage *page_next() const { return p_next; }
ConfigWizardPage* page_prev() const { return p_prev; }
ConfigWizardPage* page_next() const { return p_next; }
ConfigWizardPage* chain(ConfigWizardPage *page);
void append_text(wxString text);
void append_widget(wxWindow *widget, int proportion = 0);
void append_widget(wxWindow *widget, int proportion = 0, int flag = wxEXPAND|wxTOP|wxBOTTOM, int border = 10);
template<class T>
void append_thing(T *thing, int proportion = 0, int flag = wxEXPAND|wxTOP|wxBOTTOM, int border = 10)
{
content->Add(thing, proportion, flag, border);
}
// TODO: remove:
void append_sizer(wxSizer *sizer, int proportion = 0);
void append_spacer(int space);
ConfigWizard::priv *wizard_p() const { return parent->p.get(); }
virtual bool Show(bool show = true);
@ -60,7 +72,7 @@ struct PageWelcome: ConfigWizardPage
wxPanel *others_buttons;
unsigned variants_checked;
PageWelcome(ConfigWizard *parent, const PresetBundle &bundle);
PageWelcome(ConfigWizard *parent);
virtual wxPanel* extra_buttons() { return others_buttons; }
virtual void on_page_set();
@ -70,6 +82,9 @@ struct PageWelcome: ConfigWizardPage
struct PageUpdate: ConfigWizardPage
{
bool version_check;
bool preset_update;
PageUpdate(ConfigWizard *parent);
void presets_update_enable(bool enable);
@ -124,6 +139,9 @@ private:
struct ConfigWizard::priv
{
ConfigWizard *q;
AppConfig appconfig_vendors;
PresetBundle bundle_vendors;
wxBoxSizer *topsizer = nullptr;
wxBoxSizer *btnsizer = nullptr;
ConfigWizardPage *page_current = nullptr;
@ -143,6 +161,7 @@ struct ConfigWizard::priv
priv(ConfigWizard *q) : q(q) {}
void load_vendors();
void add_page(ConfigWizardPage *page);
void index_refresh();
void set_page(ConfigWizardPage *page);
@ -152,6 +171,7 @@ struct ConfigWizard::priv
void on_other_vendors();
void on_custom_setup();
void on_finish();
};

View file

@ -353,18 +353,13 @@ void add_debug_menu(wxMenuBar *menu, int event_language_change)
//#endif
}
void open_config_wizard()
void open_config_wizard(PresetBundle *preset_bundle)
{
if (g_wxMainFrame == nullptr) {
throw std::runtime_error("Main frame not set");
}
// auto *wizard = new ConfigWizard(static_cast<wxWindow*>(g_wxMainFrame)); // FIXME: lifetime
// wizard->run();
ConfigWizard::run(g_wxMainFrame);
// show_info(g_wxMainFrame, "After wizard", "After wizard");
ConfigWizard::run(g_wxMainFrame, preset_bundle);
}
void open_preferences_dialog(int event_preferences)

View file

@ -86,7 +86,7 @@ wxColour* get_sys_label_clr();
void add_debug_menu(wxMenuBar *menu, int event_language_change);
// Opens the first-time configuration wizard
void open_config_wizard();
void open_config_wizard(PresetBundle *preset_bundle);
// Create "Preferences" dialog after selecting menu "Preferences" in Perl part
void open_preferences_dialog(int event_preferences);

View file

@ -2,6 +2,7 @@
#include <cassert>
#include "Preset.hpp"
#include "AppConfig.hpp"
#include <fstream>
#include <boost/filesystem.hpp>
@ -175,6 +176,16 @@ bool Preset::update_compatible_with_printer(const Preset &active_printer, const
return this->is_compatible = is_compatible_with_printer(active_printer, extra_config);
}
void Preset::set_visible_from_appconfig(const AppConfig &app_config)
{
if (vendor == nullptr) { return; }
const std::string &model = config.opt_string("printer_model");
const std::string &variant = config.opt_string("printer_variant");
if (model.empty() || variant.empty()) { return; }
is_visible = app_config.get_variant(vendor->id, model, variant);
std::cerr << vendor->id << " / " << model << " / " << variant << ": visible: " << is_visible << std::endl;
}
const std::vector<std::string>& Preset::print_options()
{
static std::vector<std::string> s_opts {

View file

@ -13,6 +13,8 @@ class wxItemContainer;
namespace Slic3r {
class AppConfig;
enum ConfigFileType
{
CONFIG_FILE_TYPE_UNKNOWN,
@ -35,14 +37,14 @@ public:
PrinterVariant() {}
PrinterVariant(const std::string &name) : name(name) {}
std::string name;
bool enabled = true;
// bool enabled = true; // TODO: remove these?
};
struct PrinterModel {
PrinterModel() {}
std::string id;
std::string name;
bool enabled = true;
// bool enabled = true;
std::vector<PrinterVariant> variants;
PrinterVariant* variant(const std::string &name) {
for (auto &v : this->variants)
@ -85,7 +87,7 @@ public:
bool is_external = false;
// System preset is read-only.
bool is_system = false;
// Preset is visible, if it is compatible with the active Printer.
// Preset is visible, if it is compatible with the active Printer. TODO: fix
// Also the "default" preset is only visible, if it is the only preset in the list.
bool is_visible = true;
// Has this preset been modified?
@ -131,6 +133,9 @@ public:
// Mark this preset as compatible if it is compatible with active_printer.
bool update_compatible_with_printer(const Preset &active_printer, const DynamicPrintConfig *extra_config);
// Set is_visible according to application config
void set_visible_from_appconfig(const AppConfig &app_config);
// Resize the extruder specific fields, initialize them with the content of the 1st extruder.
void set_num_extruders(unsigned int n) { set_num_extruders(this->config, n); }
@ -162,6 +167,13 @@ public:
PresetCollection(Preset::Type type, const std::vector<std::string> &keys);
~PresetCollection();
typedef std::deque<Preset>::iterator Iterator;
typedef std::deque<Preset>::const_iterator ConstIterator;
Iterator begin() { return m_presets.begin() + 1; }
ConstIterator begin() const { return m_presets.begin() + 1; }
Iterator end() { return m_presets.end(); }
ConstIterator end() const { return m_presets.end(); }
void reset(bool delete_files);
Preset::Type type() const { return m_type; }

View file

@ -4,6 +4,7 @@
#include "PresetBundle.hpp"
#include "BitmapCache.hpp"
#include <iostream> // XXX
#include <algorithm>
#include <fstream>
#include <boost/filesystem.hpp>
@ -105,7 +106,7 @@ void PresetBundle::setup_directories()
std::initializer_list<boost::filesystem::path> paths = {
data_dir,
data_dir / "vendor",
data_dir / "cache",
data_dir / "cache", // TODO: rename as vendor-cache? (Check usage elsewhere!)
#ifdef SLIC3R_PROFILE_USE_PRESETS_SUBDIR
// Store the print/filament/printer presets into a "presets" directory.
data_dir / "presets",
@ -200,8 +201,12 @@ static inline std::string remove_ini_suffix(const std::string &name)
// If the "vendor" section is missing, enable all models and variants of the particular vendor.
void PresetBundle::load_installed_printers(const AppConfig &config)
{
// TODO
// m_storage
std::cerr << "load_installed_printers()" << std::endl;
for (auto &preset : printers) {
std::cerr << "preset: printer: " << preset.name << std::endl;
preset.set_visible_from_appconfig(config);
}
}
// Load selections (current print, current filaments, current printer) from config.ini
@ -221,6 +226,10 @@ void PresetBundle::load_selections(const AppConfig &config)
break;
this->set_filament_preset(i, remove_ini_suffix(config.get("presets", name)));
}
// Update visibility of presets based on application vendor / model / variant configuration.
this->load_installed_printers(config);
// Update visibility of presets based on their compatibility with the active printer.
// Always try to select a compatible print and filament preset to the current printer preset,
// as the application may have been closed with an active "external" preset, which does not
@ -708,6 +717,11 @@ static void load_vendor_profile(const boost::property_tree::ptree &tree, VendorP
void PresetBundle::install_vendor_configbundle(const std::string &src_path0)
{
boost::filesystem::path src_path(src_path0);
install_vendor_configbundle(src_path);
}
void PresetBundle::install_vendor_configbundle(const boost::filesystem::path &src_path)
{
boost::filesystem::copy_file(src_path, (boost::filesystem::path(data_dir()) / "vendor" / src_path.filename()).make_preferred(), boost::filesystem::copy_option::overwrite_if_exists);
}

View file

@ -5,6 +5,7 @@
#include "Preset.hpp"
#include <set>
#include <boost/filesystem/path.hpp>
namespace Slic3r {
@ -88,6 +89,7 @@ public:
// Install the Vendor specific config bundle into user's directory.
void install_vendor_configbundle(const std::string &src_path);
static void install_vendor_configbundle(const boost::filesystem::path &src_path);
// Export a config bundle file containing all the presets and the names of the active presets.
void export_configbundle(const std::string &path); // , const DynamicPrintConfig &settings);

View file

@ -11,9 +11,9 @@
#include "libslic3r/Utils.hpp"
#include "slic3r/GUI/GUI.hpp"
// #include "slic3r/GUI/AppConfig.hpp"
#include "slic3r/GUI/PresetBundle.hpp"
#include "slic3r/Utils/Http.hpp"
#include "slic3r/Utils/Semver.hpp"
namespace fs = boost::filesystem;