diff --git a/src/libslic3r/Utils.hpp b/src/libslic3r/Utils.hpp index ae3d0c0d4..cbf73761f 100644 --- a/src/libslic3r/Utils.hpp +++ b/src/libslic3r/Utils.hpp @@ -73,11 +73,11 @@ enum CopyFileResult { FAIL_CHECK_TARGET_NOT_OPENED }; // Copy a file, adjust the access attributes, so that the target is writable. -CopyFileResult copy_file_inner(const std::string &from, const std::string &to); +CopyFileResult copy_file_inner(const std::string &from, const std::string &to, boost::system::error_code& error_code); // Copy file to a temp file first, then rename it to the final file name. // If with_check is true, then the content of the copied file is compared to the content // of the source file before renaming. -extern CopyFileResult copy_file(const std::string &from, const std::string &to, const bool with_check = false); +extern CopyFileResult copy_file(const std::string &from, const std::string &to, boost::system::error_code& error_code, const bool with_check = false); // Compares two files if identical. extern CopyFileResult check_copy(const std::string& origin, const std::string& copy); diff --git a/src/libslic3r/utils.cpp b/src/libslic3r/utils.cpp index b084059f5..88c5c52e0 100644 --- a/src/libslic3r/utils.cpp +++ b/src/libslic3r/utils.cpp @@ -417,7 +417,7 @@ std::error_code rename_file(const std::string &from, const std::string &to) #endif } -CopyFileResult copy_file_inner(const std::string& from, const std::string& to) +CopyFileResult copy_file_inner(const std::string& from, const std::string& to, boost::system::error_code &error_code) { const boost::filesystem::path source(from); const boost::filesystem::path target(to); @@ -429,20 +429,30 @@ CopyFileResult copy_file_inner(const std::string& from, const std::string& to) // the copy_file() function will fail appropriately and we don't want the permission() // calls to cause needless failures on permissionless filesystems (ie. FATs on SD cards etc.) // or when the target file doesn't exist. + + //This error code is ignored boost::system::error_code ec; - boost::filesystem::permissions(target, perms, ec); - boost::filesystem::copy_file(source, target, boost::filesystem::copy_option::overwrite_if_exists, ec); - if (ec) { + + boost::filesystem::permissions(target, perms, error_code); + if (ec) + BOOST_LOG_TRIVIAL(error) << "Copy file permisions before copy error message: " << ec.message(); + // This error code is passed up + error_code.clear(); + boost::filesystem::copy_file(source, target, boost::filesystem::copy_option::overwrite_if_exists, error_code); + if (error_code) { return FAIL_COPY_FILE; } - boost::filesystem::permissions(target, perms, ec); + ec.clear(); + boost::filesystem::permissions(target, perms, error_code); + if (ec) + BOOST_LOG_TRIVIAL(error) << "Copy file permisions after copy error message: " << ec.message(); return SUCCESS; } -CopyFileResult copy_file(const std::string &from, const std::string &to, const bool with_check) +CopyFileResult copy_file(const std::string &from, const std::string &to, boost::system::error_code &error_code, const bool with_check) { std::string to_temp = to + ".tmp"; - CopyFileResult ret_val = copy_file_inner(from,to_temp); + CopyFileResult ret_val = copy_file_inner(from, to_temp, error_code); if(ret_val == SUCCESS) { if (with_check) diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 656e9d459..9f4616560 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -137,11 +137,12 @@ void BackgroundSlicingProcess::process_fff() //FIXME localize the messages // Perform the final post-processing of the export path by applying the print statistics over the file name. std::string export_path = m_fff_print->print_statistics().finalize_output_path(m_export_path); - int copy_ret_val = copy_file(m_temp_output_path, export_path, m_export_path_on_removable_media); + boost::system::error_code error_code; + int copy_ret_val = copy_file(m_temp_output_path, export_path, error_code, m_export_path_on_removable_media); switch (copy_ret_val) { case SUCCESS: break; // no error case FAIL_COPY_FILE: - throw Slic3r::RuntimeError(_utf8(L("Copying of the temporary G-code to the output G-code failed. Maybe the SD card is write locked?"))); + throw Slic3r::RuntimeError((boost::format(_utf8(L("Copying of the temporary G-code to the output G-code failed. Maybe the SD card is write locked?\nError message: %1%"))) % error_code.message()).str()); break; case FAIL_FILES_DIFFERENT: throw Slic3r::RuntimeError((boost::format(_utf8(L("Copying of the temporary G-code to the output G-code failed. There might be problem with target device, please try exporting again or using different device. The corrupted output G-code is at %1%.tmp."))) % export_path).str()); @@ -156,7 +157,7 @@ void BackgroundSlicingProcess::process_fff() throw Slic3r::RuntimeError((boost::format(_utf8(L("Copying of the temporary G-code has finished but the exported code couldn't be opened during copy check. The output G-code is at %1%.tmp."))) % export_path).str()); break; default: - BOOST_LOG_TRIVIAL(warning) << "Unexpected fail code(" << (int)copy_ret_val << ") durring copy_file() to " << export_path << "."; + BOOST_LOG_TRIVIAL(error) << "Unexpected fail code(" << (int)copy_ret_val << ") durring copy_file() to " << export_path << "."; break; } @@ -521,7 +522,8 @@ void BackgroundSlicingProcess::prepare_upload() if (m_print == m_fff_print) { m_print->set_status(95, _utf8(L("Running post-processing scripts"))); - if (copy_file(m_temp_output_path, source_path.string()) != SUCCESS) { + boost::system::error_code error_code; + if (copy_file(m_temp_output_path, source_path.string(), error_code) != SUCCESS) { throw Slic3r::RuntimeError(_utf8(L("Copying of the temporary G-code to the output G-code failed"))); } run_post_process_scripts(source_path.string(), m_fff_print->config()); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index b62ff4dcc..80071c972 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1770,7 +1770,8 @@ struct Plater::priv // Caching last value of show_action_buttons parameter for show_action_buttons(), so that a callback which does not know this state will not override it. mutable bool ready_to_slice = { false }; // Flag indicating that the G-code export targets a removable device, therefore the show_action_buttons() needs to be called at any case when the background processing finishes. - bool writing_to_removable_device = { false }; + bool writing_to_removable_device { false }; + bool show_ExportToRemovableFinished_notification { false }; bool inside_snapshot_capture() { return m_prevent_snapshots != 0; } bool process_completed_with_error { false }; private: @@ -3506,6 +3507,8 @@ void Plater::priv::on_export_began(wxCommandEvent& evt) { if (show_warning_dialog) warnings_dialog(); + if (this->writing_to_removable_device) + this->show_ExportToRemovableFinished_notification = true; } void Plater::priv::on_slicing_began() { @@ -3616,16 +3619,17 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt) if (wxGetApp().get_mode() == comSimple) sidebar->set_btn_label(ActionButtonType::abReslice, "Slice now"); show_action_buttons(true); + } else { + if(wxGetApp().get_mode() == comSimple) { + show_action_buttons(false); + } + // If writing to removable drive was scheduled, show notification with eject button + if (this->writing_to_removable_device && this->show_ExportToRemovableFinished_notification) { + show_action_buttons(false); + notification_manager->push_notification(NotificationType::ExportToRemovableFinished, *q->get_current_canvas3D()); + } } - else if (wxGetApp().get_mode() == comSimple) - { - show_action_buttons(false); - } - else if (this->writing_to_removable_device) - { - show_action_buttons(false); - notification_manager->push_notification(NotificationType::ExportToRemovableFinished, *q->get_current_canvas3D()); - } + this->show_ExportToRemovableFinished_notification = false; this->writing_to_removable_device = false; } @@ -4989,12 +4993,13 @@ void Plater::export_gcode(bool prefer_removable) if (! output_path.empty()) { bool path_on_removable_media = removable_drive_manager.set_and_verify_last_save_path(output_path.string()); + p->writing_to_removable_device = path_on_removable_media; p->export_gcode(output_path, path_on_removable_media, PrintHostJob()); // Storing a path to AppConfig either as path to removable media or a path to internal media. // is_path_on_removable_drive() is called with the "true" parameter to update its internal database as the user may have shuffled the external drives // while the dialog was open. appconfig.update_last_output_dir(output_path.parent_path().string(), path_on_removable_media); - p->writing_to_removable_device = path_on_removable_media; + } }