From f970741dd4f867d9d2c525fee620e45a47caa4e1 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 4 Feb 2022 09:52:00 +0100 Subject: [PATCH] Do not show ProjectDropDialog when drag and dropping a 3mf file produced by other softwares and the plater is not empty --- src/libslic3r/Format/3mf.cpp | 30 ++++++++++++++++++++++++++++++ src/libslic3r/Format/3mf.hpp | 3 +++ src/slic3r/GUI/Plater.cpp | 23 ++++++++++++++--------- 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index 0e44cc14e..446aa38ba 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -3110,6 +3110,36 @@ static void handle_legacy_project_loaded(unsigned int version_project_file, Dyna } } +bool is_project_3mf(const std::string& filename) +{ + mz_zip_archive archive; + mz_zip_zero_struct(&archive); + + if (!open_zip_reader(&archive, filename)) + return false; + + mz_uint num_entries = mz_zip_reader_get_num_files(&archive); + + // loop the entries to search for config + mz_zip_archive_file_stat stat; + bool config_found = false; + for (mz_uint i = 0; i < num_entries; ++i) { + if (mz_zip_reader_file_stat(&archive, i, &stat)) { + std::string name(stat.m_filename); + std::replace(name.begin(), name.end(), '\\', '/'); + + if (boost::algorithm::iequals(name, PRINT_CONFIG_FILE)) { + config_found = true; + break; + } + } + } + + close_zip_reader(&archive); + + return config_found; +} + bool load_3mf(const char* path, DynamicPrintConfig& config, ConfigSubstitutionContext& config_substitutions, Model* model, bool check_version) { if (path == nullptr || model == nullptr) diff --git a/src/libslic3r/Format/3mf.hpp b/src/libslic3r/Format/3mf.hpp index b91e90da7..5c2a2e672 100644 --- a/src/libslic3r/Format/3mf.hpp +++ b/src/libslic3r/Format/3mf.hpp @@ -29,6 +29,9 @@ namespace Slic3r { class DynamicPrintConfig; struct ThumbnailData; + // Returns true if the 3mf file with the given filename is a PrusaSlicer project file (i.e. if it contains a config). + extern bool is_project_3mf(const std::string& filename); + // Load the content of a 3mf file into the given model and preset bundle. extern bool load_3mf(const char* path, DynamicPrintConfig& config, ConfigSubstitutionContext& config_substitutions, Model* model, bool check_version); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 21b5c5cae..155da0b00 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -5386,17 +5386,22 @@ bool Plater::load_files(const wxArrayString& filenames) if (boost::algorithm::iends_with(filename, ".3mf") || boost::algorithm::iends_with(filename, ".amf")) { LoadType load_type = LoadType::Unknown; if (!model().objects.empty()) { - if (wxGetApp().app_config->get("show_drop_project_dialog") == "1") { - ProjectDropDialog dlg(filename); - if (dlg.ShowModal() == wxID_OK) { - int choice = dlg.get_action(); - load_type = static_cast(choice); - wxGetApp().app_config->set("drop_project_action", std::to_string(choice)); + if ((boost::algorithm::iends_with(filename, ".3mf") && !is_project_3mf(it->string())) || + (boost::algorithm::iends_with(filename, ".amf") && !boost::algorithm::iends_with(filename, ".zip.amf"))) + load_type = LoadType::OpenProject; + else { + if (wxGetApp().app_config->get("show_drop_project_dialog") == "1") { + ProjectDropDialog dlg(filename); + if (dlg.ShowModal() == wxID_OK) { + int choice = dlg.get_action(); + load_type = static_cast(choice); + wxGetApp().app_config->set("drop_project_action", std::to_string(choice)); + } } + else + load_type = static_cast(std::clamp(std::stoi(wxGetApp().app_config->get("drop_project_action")), + static_cast(LoadType::OpenProject), static_cast(LoadType::LoadConfig))); } - else - load_type = static_cast(std::clamp(std::stoi(wxGetApp().app_config->get("drop_project_action")), - static_cast(LoadType::OpenProject), static_cast(LoadType::LoadConfig))); } else load_type = LoadType::OpenProject;