Ported the AboutDialog to C++, thanks @alexrj for the work.

New "configuration" menu over the snapshots, user preferences etc.
This commit is contained in:
bubnikv 2018-04-09 17:03:37 +02:00
parent 601185f113
commit 32c4cddb91
15 changed files with 336 additions and 182 deletions

View file

@ -205,6 +205,22 @@ size_t SnapshotDB::load_db()
return m_snapshots.size();
}
void SnapshotDB::update_slic3r_versions(std::vector<Index> &index_db)
{
for (Snapshot &snapshot : m_snapshots) {
for (Snapshot::VendorConfig &vendor_config : snapshot.vendor_configs) {
auto it = std::find_if(index_db.begin(), index_db.end(), [&vendor_config](const Index &idx) { return idx.vendor() == vendor_config.name; });
if (it != index_db.end()) {
Index::const_iterator it_version = it->find(vendor_config.version);
if (it_version != it->end()) {
vendor_config.min_slic3r_version = it_version->min_slic3r_version;
vendor_config.max_slic3r_version = it_version->max_slic3r_version;
}
}
}
}
}
static void copy_config_dir_single_level(const boost::filesystem::path &path_src, const boost::filesystem::path &path_dst)
{
if (! boost::filesystem::is_directory(path_dst) &&
@ -303,6 +319,26 @@ boost::filesystem::path SnapshotDB::create_db_dir()
return snapshots_dir;
}
SnapshotDB& SnapshotDB::singleton()
{
static SnapshotDB instance;
bool loaded = false;
if (! loaded) {
try {
loaded = true;
// Load the snapshot database.
instance.load_db();
// Load the vendor specific configuration indices.
std::vector<Index> index_db = Index::load_db();
// Update the min / max slic3r versions compatible with the configurations stored inside the snapshots
// based on the min / max slic3r versions defined by the vendor specific config indices.
instance.update_slic3r_versions(index_db);
} catch (std::exception &ex) {
}
}
return instance;
}
} // namespace Config
} // namespace GUI
} // namespace Slic3r

View file

@ -6,6 +6,7 @@
#include <boost/filesystem.hpp>
#include "Version.hpp"
#include "../Utils/Semver.hpp"
namespace Slic3r {
@ -15,6 +16,8 @@ class AppConfig;
namespace GUI {
namespace Config {
class Version;
// A snapshot contains:
// Slic3r.ini
// vendor/
@ -75,12 +78,16 @@ public:
class SnapshotDB
{
public:
// Initialize the SnapshotDB singleton instance. Load the database if it has not been loaded yet.
static SnapshotDB& singleton();
typedef std::vector<Snapshot>::const_iterator const_iterator;
// Load the snapshot database from the snapshots directory.
// If the snapshot directory or its parent does not exist yet, it will be created.
// Returns a number of snapshots loaded.
size_t load_db();
void update_slic3r_versions(std::vector<Index> &index_db);
// Create a snapshot directory, copy the vendor config bundles, user print/filament/printer profiles,
// create an index.

View file

@ -6,6 +6,8 @@
#include "../../libslic3r/libslic3r.h"
#include "../../libslic3r/Config.hpp"
#include "../../libslic3r/FileParserError.hpp"
#include "../../libslic3r/Utils.hpp"
namespace Slic3r {
namespace GUI {
@ -62,11 +64,12 @@ inline std::string unquote_version_comment(char *value, char *end, const std::st
return svalue;
}
size_t Index::load(const std::string &path)
size_t Index::load(const boost::filesystem::path &path)
{
m_configs.clear();
m_vendor = path.stem().string();
boost::nowide::ifstream ifs(path);
boost::nowide::ifstream ifs(path.string());
std::string line;
size_t idx_line = 0;
Version ver;
@ -96,7 +99,7 @@ size_t Index::load(const std::string &path)
if (semver)
throw file_parser_error("Key cannot be a semantic version", path, idx_line);
// Verify validity of the key / value pair.
std::string svalue = unquote_value(left_trim(++ value), end, path, idx_line);
std::string svalue = unquote_value(left_trim(++ value), end, path.string(), idx_line);
if (key == "min_sic3r_version" || key == "max_slic3r_version") {
if (! svalue.empty())
semver = Semver::parse(key);
@ -113,13 +116,24 @@ size_t Index::load(const std::string &path)
if (! semver)
throw file_parser_error("Invalid semantic version", path, idx_line);
ver.config_version = *semver;
ver.comment = (end <= key_end) ? "" : unquote_version_comment(value, end, path, idx_line);
ver.comment = (end <= key_end) ? "" : unquote_version_comment(value, end, path.string(), idx_line);
m_configs.emplace_back(ver);
}
// Sort the configs by their version.
std::sort(m_configs.begin(), m_configs.end(), [](const Version &v1, const Version &v2) { return v1.config_version < v2.config_version; });
return m_configs.size();
}
Index::const_iterator Index::find(const Semver &ver)
{
Version key;
key.config_version = ver;
auto it = std::lower_bound(m_configs.begin(), m_configs.end(), key,
[](const Version &v1, const Version &v2) { return v1.config_version < v2.config_version; });
return (it == m_configs.end() || it->config_version == ver) ? it : m_configs.end();
}
Index::const_iterator Index::recommended() const
{
int idx = -1;
@ -131,6 +145,31 @@ Index::const_iterator Index::recommended() const
return highest;
}
std::vector<Index> Index::load_db()
{
boost::filesystem::path data_dir = boost::filesystem::path(Slic3r::data_dir());
boost::filesystem::path vendor_dir = data_dir / "vendor";
std::vector<Index> index_db;
std::string errors_cummulative;
for (auto &dir_entry : boost::filesystem::directory_iterator(vendor_dir))
if (boost::filesystem::is_regular_file(dir_entry.status()) && boost::algorithm::iends_with(dir_entry.path().filename().string(), ".idx")) {
Index idx;
try {
idx.load(dir_entry.path());
} catch (const std::runtime_error &err) {
errors_cummulative += err.what();
errors_cummulative += "\n";
continue;
}
index_db.emplace_back(std::move(idx));
}
if (! errors_cummulative.empty())
throw std::runtime_error(errors_cummulative);
return index_db;
}
} // namespace Config
} // namespace GUI
} // namespace Slic3r

View file

@ -4,6 +4,8 @@
#include <string>
#include <vector>
#include <boost/filesystem.hpp>
#include "../../libslic3r/FileParserError.hpp"
#include "../Utils/Semver.hpp"
@ -54,17 +56,25 @@ public:
typedef std::vector<Version>::const_iterator const_iterator;
// Read a config index file in the simple format described in the Index class comment.
// Throws Slic3r::file_parser_error and the standard std file access exceptions.
size_t load(const std::string &path);
size_t load(const boost::filesystem::path &path);
const std::string& vendor() const { return m_vendor; }
const_iterator begin() const { return m_configs.begin(); }
const_iterator end() const { return m_configs.end(); }
const_iterator find(const Semver &ver);
const std::vector<Version>& configs() const { return m_configs; }
// Finds a recommended config to be installed for the current Slic3r version.
// Returns configs().end() if such version does not exist in the index. This shall never happen
// if the index is valid.
const_iterator recommended() const;
// Load all vendor specific indices.
// Throws Slic3r::file_parser_error and the standard std file access exceptions.
static std::vector<Index> load_db();
private:
std::string m_vendor;
std::vector<Version> m_configs;
};