diff --git a/src/slic3r/GUI/PresetArchiveDatabase.cpp b/src/slic3r/GUI/PresetArchiveDatabase.cpp index 4dc1b4a2f6..c05b5c80a9 100644 --- a/src/slic3r/GUI/PresetArchiveDatabase.cpp +++ b/src/slic3r/GUI/PresetArchiveDatabase.cpp @@ -122,17 +122,16 @@ void delete_path_recursive(const fs::path& path) } } -bool extract_local_archive_repository(const std::string& uuid, const fs::path& zip_path, fs::path& unq_tmp_path, ArchiveRepository::RepositoryManifest& manifest_data) +bool extract_local_archive_repository( ArchiveRepository::RepositoryManifest& manifest_data) { - manifest_data.source_path = zip_path; - // Path where data will be unzipped. - manifest_data.tmp_path = unq_tmp_path / uuid; + assert(!manifest_data.tmp_path.empty()); + assert(!manifest_data.source_path.empty()); // Delete previous data before unzip. // We have unique path in temp set for whole run of slicer and in it folder for each repo. delete_path_recursive(manifest_data.tmp_path); fs::create_directories(manifest_data.tmp_path); // Unzip repository zip to unique path in temp directory. - if (!unzip_repository(zip_path, manifest_data.tmp_path)) { + if (!unzip_repository(manifest_data.source_path, manifest_data.tmp_path)) { return false; } // Read the manifest file. @@ -142,7 +141,7 @@ bool extract_local_archive_repository(const std::string& uuid, const fs::path& z pt::ptree ptree; pt::read_json(manifest_path.string(), ptree); if (!extract_repository_header(ptree, manifest_data)) { - BOOST_LOG_TRIVIAL(error) << "Failed to load repository: " << zip_path; + BOOST_LOG_TRIVIAL(error) << "Failed to load repository: " << manifest_data.tmp_path; return false; } } @@ -314,6 +313,14 @@ bool LocalArchiveRepository::get_archive(const fs::path& target_path) const return get_file_inner(std::move(source_path), target_path); } +void LocalArchiveRepository::do_extract() +{ + RepositoryManifest new_manifest; + new_manifest.source_path = this->get_manifest().source_path; + new_manifest.tmp_path = this->get_manifest().tmp_path; + m_extracted = extract_local_archive_repository(new_manifest); + set_manifest(std::move(new_manifest)); +} //-------------------------------------PresetArchiveDatabase------------------------------------------------------------------------------------------------------------------------- @@ -331,6 +338,8 @@ PresetArchiveDatabase::PresetArchiveDatabase(AppConfig* app_config, wxEvtHandler bool PresetArchiveDatabase::set_selected_repositories(const std::vector& selected_uuids, std::string& msg) { + // First re-extract locals, this will set is_extracted flag + extract_local_archives(); // Check if some uuids leads to the same id (online vs local conflict) std::map used_set; for (const std::string& uuid : selected_uuids) { @@ -345,8 +354,7 @@ bool PresetArchiveDatabase::set_selected_repositories(const std::vectoris_extracted()) { // non existent local repo since start selected msg = GUI::format( - _L("Cannot select local repository from path: %1%. It was not extracted." - " To solve this issue either remove and load it again or restart the app."), + _L("Cannot select offline repository from path: %1%. It was not extracted."), archive->get_manifest().source_path ); return false; @@ -401,7 +409,7 @@ void PresetArchiveDatabase::set_installed_printer_repositories(const std::vector std::string PresetArchiveDatabase::add_local_archive(const boost::filesystem::path path, std::string& msg) { - if (auto it = std::find_if(m_archive_repositories.begin(), m_archive_repositories.end(), [path](const std::unique_ptr& ptr) { + if (auto it = std::find_if(m_archive_repositories.begin(), m_archive_repositories.end(), [path](const std::unique_ptr& ptr) { return ptr->get_manifest().source_path == path; }); it != m_archive_repositories.end()) { @@ -411,7 +419,9 @@ std::string PresetArchiveDatabase::add_local_archive(const boost::filesystem::pa } std::string uuid = get_next_uuid(); ArchiveRepository::RepositoryManifest header_data; - if (!extract_local_archive_repository(uuid, path, m_unq_tmp_path, header_data)) { + header_data.source_path = path; + header_data.tmp_path = m_unq_tmp_path / uuid; + if (!extract_local_archive_repository(header_data)) { msg = GUI::format(_L("Failed to extract local archive %1%."), path); BOOST_LOG_TRIVIAL(error) << msg; return std::string(); @@ -426,7 +436,7 @@ std::string PresetArchiveDatabase::add_local_archive(const boost::filesystem::pa } void PresetArchiveDatabase::remove_local_archive(const std::string& uuid) { - auto compare_repo = [uuid](const std::unique_ptr& repo) { + auto compare_repo = [uuid](const std::unique_ptr& repo) { return repo->get_uuid() == uuid; }; @@ -446,6 +456,13 @@ void PresetArchiveDatabase::remove_local_archive(const std::string& uuid) save_app_manifest_json(); } + void PresetArchiveDatabase::extract_local_archives() + { + for (auto &archive : m_archive_repositories) { + archive->do_extract(); + } + } + void PresetArchiveDatabase::load_app_manifest_json() { const fs::path path = get_stored_manifest_path(); @@ -483,7 +500,9 @@ void PresetArchiveDatabase::load_app_manifest_json() if (const auto source_path = subtree.second.get_optional("source_path"); source_path) { ArchiveRepository::RepositoryManifest manifest; std::string uuid = get_next_uuid(); - bool extracted = extract_local_archive_repository(uuid, *source_path, m_unq_tmp_path, manifest); + manifest.source_path = boost::filesystem::path(*source_path); + manifest.tmp_path = m_unq_tmp_path / uuid; + bool extracted = extract_local_archive_repository(manifest); // "selected" flag if(const auto used = subtree.second.get_optional("selected"); used) { m_selected_repositories_uuid[uuid] = extracted && *used; @@ -724,7 +743,7 @@ void PresetArchiveDatabase::read_server_manifest(const std::string& json_body) std::string uuid = repo_ptr->get_uuid(); if (std::find_if( m_archive_repositories.begin(), m_archive_repositories.end(), - [uuid](const std::unique_ptr &ptr) { + [uuid](const std::unique_ptr &ptr) { return ptr->get_uuid() == uuid; } ) == m_archive_repositories.end()) @@ -741,6 +760,7 @@ void PresetArchiveDatabase::read_server_manifest(const std::string& json_body) SharedArchiveRepositoryVector PresetArchiveDatabase::get_all_archive_repositories() const { SharedArchiveRepositoryVector result; + result.reserve(m_archive_repositories.size()); for (const auto &repo_ptr : m_archive_repositories) { result.emplace_back(repo_ptr.get()); @@ -751,6 +771,7 @@ SharedArchiveRepositoryVector PresetArchiveDatabase::get_all_archive_repositorie SharedArchiveRepositoryVector PresetArchiveDatabase::get_selected_archive_repositories() const { SharedArchiveRepositoryVector result; + result.reserve(m_archive_repositories.size()); for (const auto &repo_ptr : m_archive_repositories) { auto it = m_selected_repositories_uuid.find(repo_ptr->get_uuid()); @@ -780,7 +801,7 @@ bool PresetArchiveDatabase::is_selected_repository_by_id(const std::string& repo } void PresetArchiveDatabase::consolidate_uuid_maps() { - //std::vector> m_archive_repositories; + //std::vector> m_archive_repositories; //std::map m_selected_repositories_uuid; auto selected_it = m_selected_repositories_uuid.begin(); while (selected_it != m_selected_repositories_uuid.end()) { diff --git a/src/slic3r/GUI/PresetArchiveDatabase.hpp b/src/slic3r/GUI/PresetArchiveDatabase.hpp index 7d33ec5536..c693632f96 100644 --- a/src/slic3r/GUI/PresetArchiveDatabase.hpp +++ b/src/slic3r/GUI/PresetArchiveDatabase.hpp @@ -87,6 +87,9 @@ public: std::string get_uuid() const { return m_uuid; } // Only local archvies can return false virtual bool is_extracted() const { return true; } + virtual void do_extract() {} + void set_manifest(RepositoryManifest &&manifest) { m_data = std::move(manifest); } + protected: RepositoryManifest m_data; std::string m_uuid; @@ -127,13 +130,14 @@ public: // Should be used only if no previous ini file exists. bool get_ini_no_id(const std::string& source_subpath, const boost::filesystem::path& target_path) const override; bool is_extracted() const override { return m_extracted; } - + void do_extract() override; + private: bool get_file_inner(const boost::filesystem::path& source_path, const boost::filesystem::path& target_path) const; bool m_extracted; }; -typedef std::vector> PrivateArchiveRepositoryVector; +typedef std::vector> PrivateArchiveRepositoryVector; typedef std::vector SharedArchiveRepositoryVector; class PresetArchiveDatabase @@ -151,6 +155,7 @@ public: bool is_selected_repository_by_uuid(const std::string& uuid) const; bool is_selected_repository_by_id(const std::string& repo_id) const; const std::map& get_selected_repositories_uuid() const { assert(m_selected_repositories_uuid.size() == m_archive_repositories.size()); return m_selected_repositories_uuid; } + // Does re-estract all local archives bool set_selected_repositories(const std::vector& used_uuids, std::string& msg); void set_installed_printer_repositories(const std::vector &used_ids); std::string add_local_archive(const boost::filesystem::path path, std::string& msg); @@ -165,6 +170,7 @@ private: bool has_installed_printers(const std::string &uuid) const; boost::filesystem::path get_stored_manifest_path() const; void consolidate_uuid_maps(); + void extract_local_archives(); std::string get_next_uuid(); wxEvtHandler* p_evt_handler; boost::filesystem::path m_unq_tmp_path;