diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index b4e5a2d9ca..3b8d74511c 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -624,7 +624,7 @@ PageUpdateManager::PageUpdateManager(ConfigWizard* parent) btn->SetFont(wxGetApp().bold_font()); wxGetApp().UpdateDarkUI(btn, true); btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) { - m_manager->set_used_archives(); + m_manager->set_selected_repositories(); wizard_p()->set_config_updated_from_archive(true); }); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index d3b9a689c8..e5931b2a8c 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -3162,7 +3162,7 @@ bool GUI_App::run_wizard(ConfigWizard::RunReason reason, ConfigWizard::StartPage } #endif // 0 // Do blocking sync on every start of wizard, so user is always offered recent profiles. - preset_updater->sync_blocking(preset_bundle, this, plater()->get_preset_archive_database()->get_archives()); + preset_updater->sync_blocking(preset_bundle, this, plater()->get_preset_archive_database()->get_archive_repositories(), plater()->get_preset_archive_database()->get_selected_repositories_uuid()); // Offer update installation (of already installed profiles) only when run by user. if (reason == ConfigWizard::RR_USER) { preset_updater->update_index_db(); @@ -3880,7 +3880,7 @@ void GUI_App::start_preset_updater(bool forced) return; } this->preset_updater->cancel_sync(); - this->preset_updater->sync(preset_bundle, this, plater()->get_preset_archive_database()->get_archives()); + this->preset_updater->sync(preset_bundle, this, plater()->get_preset_archive_database()->get_archive_repositories(), plater()->get_preset_archive_database()->get_selected_repositories_uuid()); m_started_preset_updater = true; } } // GUI diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 92e9287b0c..94070a632a 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -994,7 +994,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) } this->q->Bind(EVT_PRESET_ARCHIVE_DATABASE_SYNC_DONE, [this](Event& evt) { - preset_archive_database->set_archives(evt.data.json); + preset_archive_database->read_server_manifest(evt.data.json); wxGetApp().start_preset_updater(evt.data.force_updater); }); diff --git a/src/slic3r/GUI/PresetArchiveDatabase.cpp b/src/slic3r/GUI/PresetArchiveDatabase.cpp index 19ffbafd02..ff947ef747 100644 --- a/src/slic3r/GUI/PresetArchiveDatabase.cpp +++ b/src/slic3r/GUI/PresetArchiveDatabase.cpp @@ -14,8 +14,12 @@ #include #include #include +#include +#include #include #include +#include +#include namespace pt = boost::property_tree; namespace fs = boost::filesystem; @@ -69,21 +73,21 @@ bool extract_repository_header(const pt::ptree& ptree, ArchiveRepository::Reposi if (const auto name = ptree.get_optional("name"); name){ data.name = *name; } else { - BOOST_LOG_TRIVIAL(error) << "Failed to find \"name\" parameter in repository header. Repository is invalid."; + BOOST_LOG_TRIVIAL(error) << "Failed to find \"name\" parameter in repository manifest. Repository is invalid."; return false; } if (const auto id = ptree.get_optional("id"); id) { data.id = *id; } else { - BOOST_LOG_TRIVIAL(error) << "Failed to find \"id\" parameter in repository header. Repository is invalid."; + BOOST_LOG_TRIVIAL(error) << "Failed to find \"id\" parameter in repository manifest. Repository is invalid."; return false; } if (const auto url = ptree.get_optional("url"); url) { data.url = *url; } else { - BOOST_LOG_TRIVIAL(error) << "Failed to find \"url\" parameter in repository header. Repository is invalid."; + BOOST_LOG_TRIVIAL(error) << "Failed to find \"url\" parameter in repository manifest. Repository is invalid."; return false; } // optional atributes @@ -120,32 +124,33 @@ void delete_path_recursive(const fs::path& path) } } -bool extract_local_archive_repository(const fs::path& zip_path, fs::path& unq_tmp_path, ArchiveRepository::RepositoryManifest& header_data) +bool extract_local_archive_repository(const std::string& uuid, const fs::path& zip_path, fs::path& unq_tmp_path, ArchiveRepository::RepositoryManifest& manifest_data) { + manifest_data.source_path = zip_path; // Path where data will be unzipped. - header_data.local_path = unq_tmp_path / zip_path.stem(); + manifest_data.tmp_path = unq_tmp_path / uuid; // 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(header_data.local_path); - fs::create_directories(header_data.local_path); + 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, header_data.local_path)) { + if (!unzip_repository(zip_path, manifest_data.tmp_path)) { return false; } - // Read the header file. - fs::path header_path = header_data.local_path / "header.json"; + // Read the manifest file. + fs::path manifest_path = manifest_data.tmp_path / "manifest.json"; try { pt::ptree ptree; - pt::read_json(header_path.string(), ptree); - if (!extract_repository_header(ptree, header_data)) { + pt::read_json(manifest_path.string(), ptree); + if (!extract_repository_header(ptree, manifest_data)) { BOOST_LOG_TRIVIAL(error) << "Failed to load repository: " << zip_path; return false; } } catch (const std::exception& e) { - BOOST_LOG_TRIVIAL(error) << "Failed to read repository header JSON " << header_path << ". reason: " << e.what(); + BOOST_LOG_TRIVIAL(error) << "Failed to read repository manifest JSON " << manifest_path << ". reason: " << e.what(); return false; } return true; @@ -297,18 +302,21 @@ bool LocalArchiveRepository::get_file(const std::string& source_subpath, const f BOOST_LOG_TRIVIAL(error) << "Error getting file " << source_subpath << ". The repository_id was not matching."; return false; } - return get_file_inner(m_data.local_path / source_subpath, target_path); + return get_file_inner(m_data.tmp_path / source_subpath, target_path); } bool LocalArchiveRepository::get_ini_no_id(const std::string& source_subpath, const fs::path& target_path) const { - return get_file_inner(m_data.local_path / source_subpath, target_path); + return get_file_inner(m_data.tmp_path / source_subpath, target_path); } bool LocalArchiveRepository::get_archive(const fs::path& target_path) const { - fs::path source_path = fs::path(m_data.local_path) / "vendor_indices.zip"; + fs::path source_path = fs::path(m_data.tmp_path) / "vendor_indices.zip"; return get_file_inner(std::move(source_path), target_path); } + +//-------------------------------------PresetArchiveDatabase------------------------------------------------------------------------------------------------------------------------- + PresetArchiveDatabase::PresetArchiveDatabase(AppConfig* app_config, wxEvtHandler* evt_handler) : p_evt_handler(evt_handler) { @@ -317,62 +325,304 @@ PresetArchiveDatabase::PresetArchiveDatabase(AppConfig* app_config, wxEvtHandler fs::create_directories(m_unq_tmp_path, ec); assert(!ec); - set_local_archives(app_config); + load_app_manifest_json(); } -void PresetArchiveDatabase::set_used_archives(const std::vector& used_ids) -{ - m_used_archive_ids = used_ids; -} -void PresetArchiveDatabase::add_local_archive(const boost::filesystem::path path) -{ -} -void PresetArchiveDatabase::remove_local_archive(const std::string& id) +bool PresetArchiveDatabase::set_selected_repositories(const std::vector& selected_uuids, std::string& msg) { + // Check if some uuids leads to the same id (online vs local conflict) + std::map used_set; + for (const std::string& uuid : selected_uuids) { + std::string id; + std::string name; + for (const auto& archive : m_archive_repositories) { + if (archive->get_uuid() == uuid) { + id = archive->get_manifest().id; + name = archive->get_manifest().name; + break; + } + } + assert(!id.empty()); + if (auto it = used_set.find(id); it != used_set.end()) { + msg = GUI::format(_L("Cannot select two repositories with the same id: %1% and %2%"), it->second, name); + return false; + } + used_set.emplace(id, name); + } + // deselect all first + for (auto& pair : m_selected_repositories_uuid) { + pair.second = false; + } + for (const std::string& uuid : selected_uuids) { + m_selected_repositories_uuid[uuid] = true; + } + save_app_manifest_json(); + return true; } -void PresetArchiveDatabase::set_archives(const std::string& json_body) +bool PresetArchiveDatabase::add_local_archive(const boost::filesystem::path path, std::string& msg) { - m_archives.clear(); - // Online repo headers are in json_body. + 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()) + { + msg = GUI::format(_L("Failed to add local archive %1%. Path already used."), path); + BOOST_LOG_TRIVIAL(error) << msg; + return false; + } + std::string uuid = get_next_uuid(); + ArchiveRepository::RepositoryManifest header_data; + if (!extract_local_archive_repository(uuid, path, m_unq_tmp_path, header_data)) { + msg = GUI::format(_L("Failed to extract local archive %1%."), path); + BOOST_LOG_TRIVIAL(error) << msg; + return false; + } + // Solve if it can be set true first. + m_selected_repositories_uuid[uuid] = false; + m_archive_repositories.emplace_back(std::make_unique(uuid, std::move(header_data))); + + save_app_manifest_json(); + return true; +} +void PresetArchiveDatabase::remove_local_archive(const std::string& uuid) +{ + auto compare_repo = [uuid](const std::unique_ptr& repo) { + return repo->get_uuid() == uuid; + }; + + auto archives_it = std::find_if(m_archive_repositories.begin(), m_archive_repositories.end(), compare_repo); + assert(archives_it != m_archive_repositories.end()); + std::string removed_uuid = archives_it->get()->get_uuid(); + m_archive_repositories.erase(archives_it); + + auto used_it = m_selected_repositories_uuid.find(removed_uuid); + assert(used_it != m_selected_repositories_uuid.end()); + m_selected_repositories_uuid.erase(used_it); + + save_app_manifest_json(); +} + +void PresetArchiveDatabase::load_app_manifest_json() +{ + std::string path = get_stored_manifest_path(); + std::ifstream file(path); + std::string data; + if (file.is_open()) { + std::string line; + while (getline(file, line)) { + data += line; + } + file.close(); + } + else { + assert(true); + BOOST_LOG_TRIVIAL(error) << "Failed to read Archive Repository Manifest at " << path; + } + if (data.empty()) { + return; + } + + m_archive_repositories.clear(); try { - std::stringstream ss(json_body); + std::stringstream ss(data); pt::ptree ptree; - pt::read_json(ss, ptree); + pt::read_json(ss, ptree); for (const auto& subtree : ptree) { - ArchiveRepository::RepositoryManifest header; - if (extract_repository_header(subtree.second, header)) { - m_archives.emplace_back(std::make_unique(std::move(header))); - } else { - BOOST_LOG_TRIVIAL(error) << "Failed to read one of repository headers."; + // if has tmp_path its local repo else its online repo (manifest is written in its zip, not in our json) + if (const auto source_path = subtree.second.get_optional("source_path"); source_path) { + ArchiveRepository::RepositoryManifest manifest; + std::string uuid = get_next_uuid(); + if (!extract_local_archive_repository(uuid, *source_path, m_unq_tmp_path, manifest)) { + BOOST_LOG_TRIVIAL(error) << "Local archive repository not extracted: " << *source_path; + continue; + } + if(const auto used = subtree.second.get_optional("selected"); used) { + m_selected_repositories_uuid[uuid] = *used; + } else { + assert(true); + } + m_archive_repositories.emplace_back(std::make_unique(std::move(uuid), std::move(manifest))); + + continue; } + // online repo + ArchiveRepository::RepositoryManifest manifest; + std::string uuid = get_next_uuid(); + if (!extract_repository_header(subtree.second, manifest)) { + assert(true); + BOOST_LOG_TRIVIAL(error) << "Failed to read one of repository headers."; + continue; + } + auto search = m_selected_repositories_uuid.find(uuid); + assert(search == m_selected_repositories_uuid.end()); + if (const auto used = subtree.second.get_optional("selected"); used) { + m_selected_repositories_uuid[uuid] = *used; + } else { + assert(true); + } + m_archive_repositories.emplace_back(std::make_unique(std::move(uuid), std::move(manifest))); } } catch (const std::exception& e) { BOOST_LOG_TRIVIAL(error) << "Failed to read archives JSON. " << e.what(); } - // Local archives are stored as paths to zip. - // PresetArchiveDatabase has its folder in temp, local archives are extracted there - for (const std::string& archive_opt : m_local_archive_adresses) { - ArchiveRepository::RepositoryManifest header_data; - if (extract_local_archive_repository(archive_opt, m_unq_tmp_path, header_data)) { - m_archives.emplace_back(std::make_unique(std::move(header_data))); - } +} +void PresetArchiveDatabase::save_app_manifest_json() const +{ + /* + [{ + "name": "Production", + "description": "Production repository", + "visibility": null, + "id": "prod", + "url": "http://10.24.3.3:8001/v1/repos/prod", + "index_url": "http://10.24.3.3:8001/v1/repos/prod/vendor_indices.zip" + }, { + "name": "Development", + "description": "Production repository", + "visibility": null, + "id": "dev", + "url": "http://10.24.3.3:8001/v1/repos/dev", + "index_url": "http://10.24.3.3:8001/v1/repos/dev/vendor_indices.zip" + }] + */ + std::string data = "["; + + for (const auto& archive : m_archive_repositories) { + // local writes only source_path and "selected". Rest is read from zip on source_path. + if (!archive->get_manifest().tmp_path.empty()) { + const ArchiveRepository::RepositoryManifest& man = archive->get_manifest(); + std::string line = archive == m_archive_repositories.front() ? std::string() : ","; + line += GUI::format( + "{\"source_path\": \"%1%\"," + "\"selected\": %2%}" + , man.source_path.generic_string(), is_selected(archive->get_uuid()) ? "1" : "0"); + data += line; + continue; + } + // online repo writes whole manifest - in case of offline run, this info is load from here + const ArchiveRepository::RepositoryManifest& man = archive->get_manifest(); + std::string line = archive == m_archive_repositories.front() ? std::string() : ","; + line += GUI::format( + "{\"name\": \"%1%\"," + "\"description\": \"%2%\"," + "\"visibility\": \"%3%\"," + "\"id\": \"%4%\"," + "\"url\": \"%5%\"," + "\"index_url\": \"%6%\"," + "\"selected\": %7%}" + , man.name, man.description, man. visibility, man.id, man.url, man.index_url, is_selected(archive->get_uuid()) ? "1" : "0"); + data += line; } - m_used_archive_ids.clear(); - m_used_archive_ids.reserve(m_archives.size()); - for (const auto& archive : m_archives) { - m_used_archive_ids.emplace_back(archive->get_manifest().id); + data += "]"; + + std::string path = get_stored_manifest_path(); + std::ofstream file(path); + if (file.is_open()) { + file << data; + file.close(); + } else { + assert(true); + BOOST_LOG_TRIVIAL(error) << "Failed to write Archive Repository Manifest to " << path; } } -void PresetArchiveDatabase::set_local_archives(AppConfig* app_config) +std::string PresetArchiveDatabase::get_stored_manifest_path() const { - m_local_archive_adresses.clear(); - std::string opt = app_config->get("local_archives"); - deserialize_string(opt, m_local_archive_adresses); + return (boost::filesystem::path(Slic3r::data_dir()) / "ArchiveRepositoryManifest.json").make_preferred().string(); +} + +bool PresetArchiveDatabase::is_selected(const std::string& uuid) const +{ + auto search = m_selected_repositories_uuid.find(uuid); + assert(search != m_selected_repositories_uuid.end()); + return search->second; +} + +void PresetArchiveDatabase::clear_online_repos() +{ + auto it = m_archive_repositories.begin(); + while (it != m_archive_repositories.end()) { + if ((*it)->get_manifest().tmp_path.empty()) { + it = m_archive_repositories.erase(it); + } else { + ++it; + } + } +} + +void PresetArchiveDatabase::read_server_manifest(const std::string& json_body) +{ + pt::ptree ptree; + try + { + std::stringstream ss(json_body); + pt::read_json(ss, ptree); + } + catch (const std::exception& e) + { + BOOST_LOG_TRIVIAL(error) << "Failed to read archives JSON. " << e.what(); + + } + // Online repo manifests are in json_body. We already read local manifest and online manifest from last run. + // Keep the local ones and replace the online ones but keep uuid for same id so the selected map is correct. + // Solution: Create id - uuid translate table for online repos. + std::map id_to_uuid; + for (const auto& repo_ptr : m_archive_repositories) { + if (repo_ptr->get_manifest().source_path.empty()){ + id_to_uuid[repo_ptr->get_manifest().id] = repo_ptr->get_uuid(); + } + } + clear_online_repos(); + + for (const auto& subtree : ptree) { + ArchiveRepository::RepositoryManifest manifest; + if (!extract_repository_header(subtree.second, manifest)) { + assert(true); + BOOST_LOG_TRIVIAL(error) << "Failed to read one of repository headers."; + continue; + } + auto id_it = id_to_uuid.find(manifest.id); + std::string uuid = (id_it == id_to_uuid.end() ? get_next_uuid() : id_it->second); + // Set default used value to true - its a never before seen repository + if (auto search = m_selected_repositories_uuid.find(uuid); search == m_selected_repositories_uuid.end()) { + m_selected_repositories_uuid[uuid] = true; + } + m_archive_repositories.emplace_back(std::make_unique(uuid, std::move(manifest))); + } + + consolidate_selected_uuids_map(); + save_app_manifest_json(); +} + + +void PresetArchiveDatabase::consolidate_selected_uuids_map() +{ + //std::vector> m_archive_repositories; + //std::map m_selected_repositories_uuid; + auto it = m_selected_repositories_uuid.begin(); + while (it != m_selected_repositories_uuid.end()) { + bool found = false; + for (const auto& repo_ptr : m_archive_repositories) { + if (repo_ptr->get_uuid() == it->first) { + found = true; + break; + } + } + if (!found) { + it = m_selected_repositories_uuid.erase(it); + } else { + ++it; + } + } +} + +std::string PresetArchiveDatabase::get_next_uuid() +{ + boost::uuids::uuid uuid = m_uuid_generator(); + return boost::uuids::to_string(uuid); } namespace { @@ -419,7 +669,7 @@ void PresetArchiveDatabase::sync_blocking() std::string manifest; if (!sync_inner(manifest)) return; - set_archives(std::move(manifest)); + read_server_manifest(std::move(manifest)); } }} // Slic3r::GUI \ No newline at end of file diff --git a/src/slic3r/GUI/PresetArchiveDatabase.hpp b/src/slic3r/GUI/PresetArchiveDatabase.hpp index 722963a784..e50f0ca804 100644 --- a/src/slic3r/GUI/PresetArchiveDatabase.hpp +++ b/src/slic3r/GUI/PresetArchiveDatabase.hpp @@ -3,6 +3,8 @@ #include "Event.hpp" +#include + #include #include #include @@ -43,11 +45,12 @@ public: std::string description; std::string visibility; // not read from manifest json - boost::filesystem::path local_path; + boost::filesystem::path tmp_path; // Where archive is unzziped. Created each app run. + boost::filesystem::path source_path; // Path given by user. Stored between app runs. bool m_secret { false }; }; // Use std::move when calling constructor. - ArchiveRepository(RepositoryManifest&& data) : m_data(std::move(data)) {} + ArchiveRepository(const std::string& uuid, RepositoryManifest&& data) : m_data(std::move(data)), m_uuid(uuid) {} virtual ~ArchiveRepository() {} // Gets vendor_indices.zip to target_path virtual bool get_archive(const boost::filesystem::path& target_path) const = 0; @@ -57,16 +60,16 @@ public: // Gets file without id check - for not yet encountered vendors only! virtual bool get_ini_no_id(const std::string& source_subpath, const boost::filesystem::path& target_path) const = 0; const RepositoryManifest& get_manifest() const { return m_data; } + std::string get_uuid() const { return m_uuid; } protected: RepositoryManifest m_data; + std::string m_uuid; }; -typedef std::vector> ArchiveRepositoryVector; - class OnlineArchiveRepository : public ArchiveRepository { public: - OnlineArchiveRepository(RepositoryManifest&& data) : ArchiveRepository(std::move(data)) + OnlineArchiveRepository(const std::string& uuid, RepositoryManifest&& data) : ArchiveRepository(uuid, std::move(data)) { if (m_data.url.back() != '/') { m_data.url += "/"; @@ -87,7 +90,7 @@ private: class LocalArchiveRepository : public ArchiveRepository { public: - LocalArchiveRepository(RepositoryManifest&& data) : ArchiveRepository(std::move(data)) {} + LocalArchiveRepository(const std::string& uuid, RepositoryManifest&& data) : ArchiveRepository(uuid, std::move(data)) {} // Gets vendor_indices.zip to target_path. bool get_archive(const boost::filesystem::path& target_path) const override; // Gets file if repository_id arg matches m_id. @@ -99,29 +102,39 @@ public: private: bool get_file_inner(const boost::filesystem::path& source_path, const boost::filesystem::path& target_path) const; }; + +typedef std::vector> ArchiveRepositoryVector; + class PresetArchiveDatabase { public: PresetArchiveDatabase(AppConfig* app_config, wxEvtHandler* evt_handler); ~PresetArchiveDatabase() {} - const ArchiveRepositoryVector& get_archives() const { return m_archives; } + const ArchiveRepositoryVector& get_archive_repositories() const { return m_archive_repositories; } void sync(); void sync_blocking(); void set_token(const std::string token) { m_token = token; } - void set_local_archives(AppConfig* app_config); - void set_archives(const std::string& json_body); - const std::vector& get_used_archives() const { return m_used_archive_ids; } - void set_used_archives(const std::vector& used_ids); - void add_local_archive(const boost::filesystem::path path); - void remove_local_archive(const std::string& id); + //void set_local_archives(AppConfig* app_config); + void read_server_manifest(const std::string& json_body); + const std::map& get_selected_repositories_uuid() const { assert(m_selected_repositories_uuid.size() == m_archive_repositories.size()); return m_selected_repositories_uuid; } + bool set_selected_repositories(const std::vector& used_uuids, std::string& msg); + bool add_local_archive(const boost::filesystem::path path, std::string& msg); + void remove_local_archive(const std::string& uuid); private: - wxEvtHandler* p_evt_handler; - boost::filesystem::path m_unq_tmp_path; - ArchiveRepositoryVector m_archives; - std::vector m_used_archive_ids; - std::vector m_local_archive_adresses; - std::string m_token; + void load_app_manifest_json(); + void save_app_manifest_json() const; + void clear_online_repos(); + bool is_selected(const std::string& id) const; + std::string get_stored_manifest_path() const; + void consolidate_selected_uuids_map(); + std::string get_next_uuid(); + wxEvtHandler* p_evt_handler; + boost::filesystem::path m_unq_tmp_path; + ArchiveRepositoryVector m_archive_repositories; + std::map m_selected_repositories_uuid; + std::string m_token; + boost::uuids::random_generator m_uuid_generator; }; }} // Slic3r::GUI diff --git a/src/slic3r/GUI/UpdatesUIManager.cpp b/src/slic3r/GUI/UpdatesUIManager.cpp index c5bdce81c1..1e3e859ad5 100644 --- a/src/slic3r/GUI/UpdatesUIManager.cpp +++ b/src/slic3r/GUI/UpdatesUIManager.cpp @@ -60,20 +60,24 @@ void UIManager::fill_entries() m_online_entries.clear(); m_offline_entries.clear(); - const ArchiveRepositoryVector& archs = m_pad->get_archives(); - const std::vector& used_archs = m_pad->get_used_archives(); + const ArchiveRepositoryVector& archs = m_pad->get_archive_repositories(); + const std::map& selected_repos = m_pad->get_selected_repositories_uuid(); for (const auto& archive : archs) { const auto& data = archive->get_manifest(); - if (data.local_path.empty()) { + if (data.source_path.empty()) { // online repo - bool is_used = std::find(used_archs.begin(), used_archs.end(), data.id) != used_archs.end(); - m_online_entries.push_back({is_used, data.id, data.name, data.description, data.visibility }); + auto selected_it = selected_repos.find(archive->get_uuid()); + assert(selected_it != selected_repos.end()); + bool is_selected = selected_it->second; + m_online_entries.push_back({is_selected, archive->get_uuid(), data.name, data.description, data.visibility }); } else { // offline repo - bool is_used = std::find(used_archs.begin(), used_archs.end(), data.id) != used_archs.end(); - m_offline_entries.push_back({is_used, data.id, data.name, data.description, data.local_path.filename().string(), fs::exists(data.local_path)}); + auto selected_it = selected_repos.find(archive->get_uuid()); + assert(selected_it != selected_repos.end()); + bool is_selected = selected_it->second; + m_offline_entries.push_back({is_selected, archive->get_uuid(), data.name, data.description, data.source_path.filename().string(), fs::exists(data.source_path)}); } } @@ -143,13 +147,13 @@ void UIManager::fill_grids() // header - for (const wxString& l : std::initializer_list{ _L("Use"), _L("Name"), _L("Descrition"), "", _L("Sourse file"), "" }) { + for (const wxString& l : std::initializer_list{ _L("Use"), _L("Name"), _L("Descrition"), "", _L("Source file"), "" }) { auto text = new wxStaticText(m_parent, wxID_ANY, l); text->SetFont(wxGetApp().bold_font()); add(text); } - // data + // data1 for (const auto& entry : m_offline_entries) { @@ -226,7 +230,11 @@ void UIManager::load_offline_repos() std::string input_file = into_u8(input_files.Item(i)); try { fs::path input_path = fs::path(input_file); - m_pad->add_local_archive(input_path); + std::string msg; + if (!m_pad->add_local_archive(input_path, msg)) + { + // Finish me. + } } catch (fs::filesystem_error const& e) { std::cerr << e.what() << '\n'; @@ -236,7 +244,7 @@ void UIManager::load_offline_repos() update(); } -void UIManager::set_used_archives() +void UIManager::set_selected_repositories() { std::vector used_ids; for (const std::string& id : m_online_selections) @@ -244,7 +252,10 @@ void UIManager::set_used_archives() for (const std::string& id : m_offline_selections) used_ids.push_back(id); - m_pad->set_used_archives(used_ids); + std::string msg; + if (!m_pad->set_selected_repositories(used_ids, msg)) { + // Finish me. + } } @@ -286,7 +297,7 @@ void ManageUpdatesDialog::onCloseDialog(wxEvent &) void ManageUpdatesDialog::onOkDialog(wxEvent&) { - m_manager->set_used_archives(); + m_manager->set_selected_repositories(); this->EndModal(wxID_CLOSE); } diff --git a/src/slic3r/GUI/UpdatesUIManager.hpp b/src/slic3r/GUI/UpdatesUIManager.hpp index 3ad9ce2289..e6c3c8bb4d 100644 --- a/src/slic3r/GUI/UpdatesUIManager.hpp +++ b/src/slic3r/GUI/UpdatesUIManager.hpp @@ -67,7 +67,7 @@ public: ~UIManager() {} wxSizer* get_sizer() { return m_main_sizer; } - void set_used_archives(); + void set_selected_repositories(); }; class ManageUpdatesDialog : public DPIDialog diff --git a/src/slic3r/Utils/PresetUpdater.cpp b/src/slic3r/Utils/PresetUpdater.cpp index f14a8accf7..a6d803b04b 100644 --- a/src/slic3r/Utils/PresetUpdater.cpp +++ b/src/slic3r/Utils/PresetUpdater.cpp @@ -1142,15 +1142,19 @@ PresetUpdater::~PresetUpdater() } } -void PresetUpdater::sync(const PresetBundle *preset_bundle, wxEvtHandler* evt_handler, const ArchiveRepositoryVector& repositories) +void PresetUpdater::sync(const PresetBundle *preset_bundle, wxEvtHandler* evt_handler, const ArchiveRepositoryVector& repositories, const std::map& selected_repo_uuids) { p->set_download_prefs(GUI::wxGetApp().app_config); if (!p->enabled_config_update) { return; } - p->thread = std::thread([this, &vendors = preset_bundle->vendors, &repositories, evt_handler]() { + p->thread = std::thread([this, &vendors = preset_bundle->vendors, &repositories, &selected_repo_uuids, evt_handler]() { this->p->prune_tmps(); for(const auto& archive : repositories) { - this->p->sync_config(vendors, *archive); + auto it = selected_repo_uuids.find(archive->get_uuid()); + assert(it != selected_repo_uuids.end()); + if (it->second) { + this->p->sync_config(vendors, *archive); + } } wxCommandEvent* evt = new wxCommandEvent(EVT_CONFIG_UPDATER_SYNC_DONE); evt_handler->QueueEvent(evt); @@ -1168,14 +1172,18 @@ void PresetUpdater::cancel_sync() p->cancel = false; } -void PresetUpdater::sync_blocking(const PresetBundle* preset_bundle, wxEvtHandler* evt_handler, const ArchiveRepositoryVector& repositories) +void PresetUpdater::sync_blocking(const PresetBundle* preset_bundle, wxEvtHandler* evt_handler, const ArchiveRepositoryVector& repositories, const std::map& selected_repo_uuids) { p->set_download_prefs(GUI::wxGetApp().app_config); if (!p->enabled_config_update) { return; } this->p->prune_tmps(); for (const auto& archive : repositories) { - this->p->sync_config(preset_bundle->vendors, *archive); + auto it = selected_repo_uuids.find(archive->get_uuid()); + assert(it != selected_repo_uuids.end()); + if (it->second) { + this->p->sync_config(preset_bundle->vendors, *archive); + } } wxCommandEvent* evt = new wxCommandEvent(EVT_CONFIG_UPDATER_SYNC_DONE); evt_handler->QueueEvent(evt); diff --git a/src/slic3r/Utils/PresetUpdater.hpp b/src/slic3r/Utils/PresetUpdater.hpp index aa86be0bfb..59520ae34d 100644 --- a/src/slic3r/Utils/PresetUpdater.hpp +++ b/src/slic3r/Utils/PresetUpdater.hpp @@ -34,10 +34,10 @@ public: ~PresetUpdater(); // If either version check or config updating is enabled, get the appropriate data in the background and cache it. - void sync(const PresetBundle *preset_bundle, wxEvtHandler* evt_handler, const ArchiveRepositoryVector& repositories); + void sync(const PresetBundle *preset_bundle, wxEvtHandler* evt_handler, const ArchiveRepositoryVector& repositories, const std::map& selected_repo_uuids); void cancel_sync(); - void sync_blocking(const PresetBundle* preset_bundle, wxEvtHandler* evt_handler, const ArchiveRepositoryVector& repositories); + void sync_blocking(const PresetBundle* preset_bundle, wxEvtHandler* evt_handler, const ArchiveRepositoryVector& repositories, const std::map& selected_repo_uuids); // If version check is enabled, check if chaced online slic3r version is newer, notify if so. void slic3r_update_notify();