mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-23 16:51:21 -06:00
ConfigWizard: Make bundle installation more intelligent, fixes
This commit is contained in:
parent
aaa8f133c0
commit
31ea03feb0
11 changed files with 159 additions and 68 deletions
|
|
@ -8,6 +8,7 @@
|
|||
#include <utility>
|
||||
#include <assert.h>
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/nowide/cenv.hpp>
|
||||
|
|
@ -228,9 +229,27 @@ bool AppConfig::version_check_enabled() const
|
|||
|
||||
bool AppConfig::slic3r_update_avail() const
|
||||
{
|
||||
// FIXME: Update with Semver
|
||||
// TODO: probably need to move semver to libslic3r
|
||||
return version_check_enabled() && get("version_online") != SLIC3R_VERSION;
|
||||
}
|
||||
|
||||
Semver AppConfig::get_slic3r_version() const
|
||||
{
|
||||
// TODO: move to Semver c-tor (???)
|
||||
auto res = Semver::parse(get("version"));
|
||||
if (! res) {
|
||||
throw std::runtime_error(std::string("Could not parse Slic3r version string in application config."));
|
||||
} else {
|
||||
return *res;
|
||||
}
|
||||
}
|
||||
|
||||
void AppConfig::set_slic3r_version(const Semver &version)
|
||||
{
|
||||
set("version", version.to_string());
|
||||
}
|
||||
|
||||
std::string AppConfig::config_path()
|
||||
{
|
||||
return (boost::filesystem::path(Slic3r::data_dir()) / "slic3r.ini").make_preferred().string();
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include <string>
|
||||
|
||||
#include "libslic3r/Config.hpp"
|
||||
#include "slic3r/Utils/Semver.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
|
@ -91,6 +92,8 @@ public:
|
|||
// Whether the Slic3r version available online differs from this one
|
||||
bool version_check_enabled() const;
|
||||
bool slic3r_update_avail() const;
|
||||
Semver get_slic3r_version() const;
|
||||
void set_slic3r_version(const Semver &version);
|
||||
|
||||
// Get the default config path from Slic3r::data_dir().
|
||||
static std::string config_path();
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include "libslic3r/Utils.hpp"
|
||||
#include "PresetBundle.hpp"
|
||||
#include "GUI.hpp"
|
||||
#include "slic3r/Utils/PresetUpdater.hpp"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
|
|
@ -699,12 +700,8 @@ ConfigWizard::~ConfigWizard() {}
|
|||
|
||||
bool ConfigWizard::run(wxWindow *parent, PresetBundle *preset_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") {
|
||||
PresetBundle::install_vendor_configbundle(it->path());
|
||||
}
|
||||
}
|
||||
// FIXME: this should be done always at app startup
|
||||
PresetUpdater::init_vendors();
|
||||
|
||||
ConfigWizard wizard(parent);
|
||||
if (wizard.ShowModal() == wxID_OK) {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <fstream>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
#include <boost/nowide/cenv.hpp>
|
||||
|
|
@ -24,14 +25,16 @@
|
|||
#include "../../libslic3r/Utils.hpp"
|
||||
#include "../../libslic3r/PlaceholderParser.hpp"
|
||||
|
||||
using boost::property_tree::ptree;
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
ConfigFileType guess_config_file_type(const boost::property_tree::ptree &tree)
|
||||
ConfigFileType guess_config_file_type(const ptree &tree)
|
||||
{
|
||||
size_t app_config = 0;
|
||||
size_t bundle = 0;
|
||||
size_t config = 0;
|
||||
for (const boost::property_tree::ptree::value_type &v : tree) {
|
||||
for (const ptree::value_type &v : tree) {
|
||||
if (v.second.empty()) {
|
||||
if (v.first == "background_processing" ||
|
||||
v.first == "last_output_path" ||
|
||||
|
|
@ -59,6 +62,74 @@ ConfigFileType guess_config_file_type(const boost::property_tree::ptree &tree)
|
|||
(bundle > config) ? CONFIG_FILE_TYPE_CONFIG_BUNDLE : CONFIG_FILE_TYPE_CONFIG;
|
||||
}
|
||||
|
||||
|
||||
VendorProfile VendorProfile::from_ini(const boost::filesystem::path &path, bool load_all)
|
||||
{
|
||||
ptree tree;
|
||||
boost::filesystem::ifstream ifs(path);
|
||||
boost::property_tree::read_ini(ifs, tree);
|
||||
return VendorProfile::from_ini(tree, path, load_all);
|
||||
}
|
||||
|
||||
VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem::path &path, bool load_all)
|
||||
{
|
||||
static const std::string printer_model_key = "printer_model:";
|
||||
const std::string id = path.stem().string();
|
||||
VendorProfile res(id);
|
||||
|
||||
auto get_or_throw = [&](const ptree &tree, const std::string &key) -> ptree::const_assoc_iterator
|
||||
{
|
||||
auto res = tree.find(key);
|
||||
if (res == tree.not_found()) {
|
||||
throw std::runtime_error((boost::format("Vendor Config Bundle `%1%` is not valid: Missing secion or key: `%2%`.") % id % key).str());
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
const auto &vendor_section = get_or_throw(tree, "vendor")->second;
|
||||
res.name = get_or_throw(vendor_section, "name")->second.data();
|
||||
|
||||
auto config_version_str = get_or_throw(vendor_section, "config_version")->second.data();
|
||||
auto config_version = Semver::parse(config_version_str);
|
||||
if (! config_version) {
|
||||
throw std::runtime_error((boost::format("Vendor Config Bundle `%1%` is not valid: Cannot parse config_version: `%2%`.") % id % config_version_str).str());
|
||||
} else {
|
||||
res.config_version = std::move(*config_version);
|
||||
}
|
||||
|
||||
auto config_update_url = vendor_section.find("config_update_url");
|
||||
if (config_update_url != vendor_section.not_found()) {
|
||||
res.config_update_url = config_update_url->second.data();
|
||||
}
|
||||
|
||||
if (! load_all) {
|
||||
return res;
|
||||
}
|
||||
|
||||
for (auto §ion : tree) {
|
||||
if (boost::starts_with(section.first, printer_model_key)) {
|
||||
VendorProfile::PrinterModel model;
|
||||
model.id = section.first.substr(printer_model_key.size());
|
||||
model.name = section.second.get<std::string>("name", model.id);
|
||||
section.second.get<std::string>("variants", "");
|
||||
std::vector<std::string> variants;
|
||||
if (Slic3r::unescape_strings_cstyle(section.second.get<std::string>("variants", ""), variants)) {
|
||||
for (const std::string &variant_name : variants) {
|
||||
if (model.variant(variant_name) == nullptr)
|
||||
model.variants.emplace_back(VendorProfile::PrinterVariant(variant_name));
|
||||
}
|
||||
} else {
|
||||
// Log error? // XXX
|
||||
}
|
||||
if (! model.id.empty() && ! model.variants.empty())
|
||||
res.models.push_back(std::move(model));
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// Suffix to be added to a modified preset name in the combo box.
|
||||
static std::string g_suffix_modified = " (modified)";
|
||||
const std::string& Preset::suffix_modified()
|
||||
|
|
|
|||
|
|
@ -3,8 +3,12 @@
|
|||
|
||||
#include <deque>
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/property_tree/ptree_fwd.hpp>
|
||||
|
||||
#include "../../libslic3r/libslic3r.h"
|
||||
#include "../../libslic3r/PrintConfig.hpp"
|
||||
#include "slic3r/Utils/Semver.hpp"
|
||||
|
||||
class wxBitmap;
|
||||
class wxChoice;
|
||||
|
|
@ -30,7 +34,7 @@ class VendorProfile
|
|||
public:
|
||||
std::string name;
|
||||
std::string id;
|
||||
std::string config_version;
|
||||
Semver config_version;
|
||||
std::string config_update_url;
|
||||
|
||||
struct PrinterVariant {
|
||||
|
|
@ -54,7 +58,10 @@ public:
|
|||
};
|
||||
std::vector<PrinterModel> models;
|
||||
|
||||
VendorProfile(std::string id) : id(std::move(id)) {}
|
||||
VendorProfile(std::string id) : id(std::move(id)), config_version(0, 0, 0) {}
|
||||
|
||||
static VendorProfile from_ini(const boost::filesystem::path &path, bool load_all=true);
|
||||
static VendorProfile from_ini(const boost::property_tree::ptree &tree, const boost::filesystem::path &path, bool load_all=true);
|
||||
|
||||
size_t num_variants() const { size_t n = 0; for (auto &model : models) n += model.variants.size(); return n; }
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ void PresetBundle::setup_directories()
|
|||
std::initializer_list<boost::filesystem::path> paths = {
|
||||
data_dir,
|
||||
data_dir / "vendor",
|
||||
data_dir / "cache", // TODO: rename as vendor-cache? (Check usage elsewhere!)
|
||||
data_dir / "cache",
|
||||
#ifdef SLIC3R_PROFILE_USE_PRESETS_SUBDIR
|
||||
// Store the print/filament/printer presets into a "presets" directory.
|
||||
data_dir / "presets",
|
||||
|
|
@ -672,42 +672,6 @@ static void flatten_configbundle_hierarchy(boost::property_tree::ptree &tree)
|
|||
flatten_configbundle_hierarchy(tree, "printer");
|
||||
}
|
||||
|
||||
static void load_vendor_profile(const boost::property_tree::ptree &tree, VendorProfile &vendor_profile)
|
||||
{
|
||||
const std::string printer_model_key = "printer_model:";
|
||||
for (auto §ion : tree) {
|
||||
if (section.first == "vendor") {
|
||||
// Load the names of the active presets.
|
||||
for (auto &kvp : section.second) {
|
||||
if (kvp.first == "name")
|
||||
vendor_profile.name = kvp.second.data();
|
||||
else if (kvp.first == "id")
|
||||
vendor_profile.id = kvp.second.data();
|
||||
else if (kvp.first == "config_version")
|
||||
vendor_profile.config_version = kvp.second.data();
|
||||
else if (kvp.first == "config_update_url")
|
||||
vendor_profile.config_update_url = kvp.second.data();
|
||||
}
|
||||
} else if (boost::starts_with(section.first, printer_model_key)) {
|
||||
VendorProfile::PrinterModel model;
|
||||
model.id = section.first.substr(printer_model_key.size());
|
||||
model.name = section.second.get<std::string>("name", model.id);
|
||||
section.second.get<std::string>("variants", "");
|
||||
std::vector<std::string> variants;
|
||||
if (Slic3r::unescape_strings_cstyle(section.second.get<std::string>("variants", ""), variants)) {
|
||||
for (const std::string &variant_name : variants) {
|
||||
if (model.variant(variant_name) == nullptr)
|
||||
model.variants.emplace_back(VendorProfile::PrinterVariant(variant_name));
|
||||
}
|
||||
} else {
|
||||
// Log error?
|
||||
}
|
||||
if (! model.id.empty() && ! model.variants.empty())
|
||||
vendor_profile.models.push_back(std::move(model));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load a config bundle file, into presets and store the loaded presets into separate files
|
||||
// of the local configuration directory.
|
||||
void PresetBundle::install_vendor_configbundle(const std::string &src_path0)
|
||||
|
|
@ -738,10 +702,7 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
|
|||
const VendorProfile *vendor_profile = nullptr;
|
||||
if (flags & (LOAD_CFGBNDLE_SYSTEM | LOAD_CFGBUNDLE_VENDOR_ONLY)) {
|
||||
boost::filesystem::path fspath(path);
|
||||
VendorProfile vp(fspath.stem().string());
|
||||
load_vendor_profile(tree, vp);
|
||||
if (vp.name.empty())
|
||||
throw std::runtime_error(std::string("Vendor Config Bundle is not valid: Missing vendor name key."));
|
||||
auto vp = VendorProfile::from_ini(tree, fspath.stem().string());
|
||||
if (vp.num_variants() == 0)
|
||||
return 0;
|
||||
vendor_profile = &(*this->vendors.insert(vp).first);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue