diff --git a/src/slic3r/GUI/MediaFilePanel.cpp b/src/slic3r/GUI/MediaFilePanel.cpp index 51ad4983b7..e4dc64dcd6 100644 --- a/src/slic3r/GUI/MediaFilePanel.cpp +++ b/src/slic3r/GUI/MediaFilePanel.cpp @@ -8,6 +8,7 @@ #include "Widgets/Label.hpp" #include "Printer/PrinterFileSystem.h" #include "MsgDialog.hpp" +#include "Widgets/ProgressDialog.hpp" #include #include @@ -446,6 +447,15 @@ void MediaFilePanel::fetchUrl(boost::weak_ptr wfs) } } +struct MediaProgressDialog : ProgressDialog +{ + MediaProgressDialog(wxString title, wxWindow * parent, std::function cancel) + : ProgressDialog(title, "", 100, parent, wxPD_NO_PROGRESS | wxPD_APP_MODAL | wxPD_CAN_ABORT) + , m_cancel(cancel) {} + void OnCancel() override{m_cancel(); } + std::function m_cancel; +}; + void Slic3r::GUI::MediaFilePanel::doAction(size_t index, int action) { auto fs = m_image_grid->GetFileSystem(); @@ -467,19 +477,30 @@ void Slic3r::GUI::MediaFilePanel::doAction(size_t index, int action) } else if (action == 1) { if (fs->GetFileType() == PrinterFileSystem::F_MODEL) { if (index != -1) { - fs->FetchModel(index, [fs,index](std::string const & data) { + auto dlg = new MediaProgressDialog(_L("Print"), this, [fs] { fs->FetchModelCancel(); }); + dlg->Update(0, _L("Fetching model infomations ...")); + fs->FetchModel(index, [this, fs, dlg, index](int result, std::string const &data) { + dlg->Destroy(); + if (result == PrinterFileSystem::ERROR_CANCEL) + return; + if (result != 0) + MessageDialog(this, + _L("Failed to fetching model infomations from printer."), + _L("Error"), wxOK).ShowModal(); Slic3r::DynamicPrintConfig config; Slic3r::Model model; Slic3r::PlateDataPtrs plate_data_list; Slic3r::Semver file_version; std::istringstream is(data); - if (!Slic3r::load_gcode_3mf_from_stream(is, &config, &model, &plate_data_list, &file_version)) + if (!Slic3r::load_gcode_3mf_from_stream(is, &config, &model, &plate_data_list, &file_version)) { + MessageDialog(this, + _L("Failed to parse model infomations."), + _L("Error"), wxOK).ShowModal(); return; - // TODO: print gcode 3mf + } auto &file = fs->GetFile(index); Slic3r::GUI::wxGetApp().plater()->update_print_required_data(config, model, plate_data_list, from_u8(file.name).ToStdString()); wxPostEvent(Slic3r::GUI::wxGetApp().plater(), SimpleEvent(EVT_PRINT_FROM_SDCARD_VIEW)); - }); } return; diff --git a/src/slic3r/GUI/Printer/PrinterFileSystem.cpp b/src/slic3r/GUI/Printer/PrinterFileSystem.cpp index fb5837cd5e..64b8947b86 100644 --- a/src/slic3r/GUI/Printer/PrinterFileSystem.cpp +++ b/src/slic3r/GUI/Printer/PrinterFileSystem.cpp @@ -275,8 +275,10 @@ void PrinterFileSystem::DownloadCancel(size_t index) file.flags &= ~FF_DOWNLOAD; } -void PrinterFileSystem::FetchModel(size_t index, std::function callback) +void PrinterFileSystem::FetchModel(size_t index, std::function callback) { + if (m_task_flags & FF_FETCH_MODEL) + return; json req; json arr; if (index == (size_t) -1) return; @@ -293,7 +295,8 @@ void PrinterFileSystem::FetchModel(size_t index, std::function( + m_task_flags |= FF_FETCH_MODEL; + m_fetch_model_seq = SendRequest( SUB_FILE, req, [](json const &resp, File &file, unsigned char const *data) -> int { // in work thread, continue recv @@ -304,11 +307,18 @@ void PrinterFileSystem::FetchModel(size_t index, std::functiongcode_prediction.c_str()); weight += atof(plate->gcode_weight.c_str()); - if (!plate->thumbnail_file.empty()) + if (!plate->gcode_file.empty() && !plate->thumbnail_file.empty()) file.metadata.emplace("plate_thumbnail_" + std::to_string(plate->plate_index), plate->thumbnail_file); } file.metadata.emplace("Title", model.model_info->model_name); @@ -937,35 +947,45 @@ void PrinterFileSystem::InstallNotify(int type, callback_t2 const &callback) m_notifies[type] = callback; } -void PrinterFileSystem::CancelRequest(boost::uint32_t seq) +void PrinterFileSystem::CancelRequest(boost::uint32_t seq) { CancelRequests({seq}); } + +void PrinterFileSystem::CancelRequests(std::vector const &seqs) { json req; json arr; - arr.push_back(seq); + for (auto seq : seqs) + arr.push_back(seq); req["tasks"] = arr; SendRequest(TASK_CANCEL, req, [this](int result, json const &resp, unsigned char const *) { if (result != 0) return; json tasks = resp["tasks"]; - std::deque callbacks; - boost::unique_lock l(m_mutex); - for (auto &f : tasks) { - boost::uint32_t seq = f; - seq -= m_sequence; - if (size_t(seq) >= m_callbacks.size()) continue; - auto & c = m_callbacks[seq]; - if (c == nullptr) continue; - callbacks.push_back(c); - m_callbacks[seq] = callback_t2(); - } - while (!m_callbacks.empty() && m_callbacks.front() == nullptr) { - m_callbacks.pop_front(); - ++m_sequence; - } - l.unlock(); - for (auto &c : callbacks) c(ERROR_CANCEL, json(), nullptr); + std::vector seqs; + for (auto &f : tasks) seqs.push_back(f); + CancelRequests2(seqs); }); } +void PrinterFileSystem::CancelRequests2(std::vector const &seqs) +{ + std::deque callbacks; + boost::unique_lock l(m_mutex); + for (auto &f : seqs) { + boost::uint32_t seq = f; + seq -= m_sequence; + if (size_t(seq) >= m_callbacks.size()) continue; + auto &c = m_callbacks[seq]; + if (c == nullptr) continue; + callbacks.push_back(c); + m_callbacks[seq] = callback_t2(); + } + while (!m_callbacks.empty() && m_callbacks.front() == nullptr) { + m_callbacks.pop_front(); + ++m_sequence; + } + l.unlock(); + for (auto &c : callbacks) c(ERROR_CANCEL, json(), nullptr); +} + void PrinterFileSystem::RecvMessageThread() { Bambu_Sample sample; diff --git a/src/slic3r/GUI/Printer/PrinterFileSystem.h b/src/slic3r/GUI/Printer/PrinterFileSystem.h index 255e2e3785..aaf1bdd217 100644 --- a/src/slic3r/GUI/Printer/PrinterFileSystem.h +++ b/src/slic3r/GUI/Printer/PrinterFileSystem.h @@ -37,6 +37,7 @@ class PrinterFileSystem : public wxEvtHandler, public boost::enable_shared_from_ TASK_CANCEL = 0x1000 }; +public: enum { SUCCESS = 0, CONTINUE = 1, @@ -89,6 +90,7 @@ public: FF_THUMNAIL = 2, // Thumbnail ready FF_DOWNLOAD = 4, // Request download FF_DELETED = 8, // Request delete + FF_FETCH_MODEL = 16,// Request model }; struct File @@ -133,7 +135,9 @@ public: void DownloadCancel(size_t index); - void FetchModel(size_t index, std::function callback); + void FetchModel(size_t index, std::function callback); + + void FetchModelCancel(); size_t GetCount() const; @@ -256,6 +260,10 @@ private: void CancelRequest(boost::uint32_t seq); + void CancelRequests(std::vector const &seqs); + + void CancelRequests2(std::vector const & seqs); + void RecvMessageThread(); void HandleResponse(boost::unique_lock &l, Bambu_Sample const &sample); @@ -297,6 +305,7 @@ private: Session m_session; boost::uint32_t m_sequence = 0; boost::uint32_t m_download_seq = 0; + boost::uint32_t m_fetch_model_seq = 0; std::deque m_messages; std::deque m_callbacks; std::deque m_notifies; diff --git a/src/slic3r/GUI/Widgets/ProgressDialog.cpp b/src/slic3r/GUI/Widgets/ProgressDialog.cpp index 8119f12844..1a0f3672db 100644 --- a/src/slic3r/GUI/Widgets/ProgressDialog.cpp +++ b/src/slic3r/GUI/Widgets/ProgressDialog.cpp @@ -223,9 +223,11 @@ bool ProgressDialog::Create(const wxString &title, const wxString &message, int maximum /= m_factor; #endif - m_gauge = new wxGauge(this, wxID_ANY, maximum, wxDefaultPosition, PROGRESSDIALOG_GAUGE_SIZE, gauge_style); - m_gauge->SetValue(0); - m_sizer_main->Add(m_gauge, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(28)); + if (!HasPDFlag(wxPD_NO_PROGRESS)) { + m_gauge = new wxGauge(this, wxID_ANY, maximum, wxDefaultPosition, PROGRESSDIALOG_GAUGE_SIZE, gauge_style); + m_gauge->SetValue(0); + m_sizer_main->Add(m_gauge, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(28)); + } #ifdef __WXMSW__ //m_block_left = new wxWindow(m_gauge, wxID_ANY, wxPoint(0, 0), wxSize(FromDIP(2), PROGRESSDIALOG_GAUGE_SIZE.y * 2)); @@ -250,6 +252,7 @@ bool ProgressDialog::Create(const wxString &title, const wxString &message, int DisableAbort(); m_button_cancel->Enable(false); DisableSkip(); + OnCancel(); m_timeStop = wxGetCurrentTime(); } }); @@ -509,14 +512,15 @@ bool ProgressDialog::Update(int value, const wxString &newmsg, bool *skip) { if (!DoBeforeUpdate(skip)) return false; - wxCHECK_MSG(m_gauge, false, "dialog should be fully created"); + wxCHECK_MSG(m_msg || m_gauge, false, "dialog should be fully created"); #ifdef __WXMSW__ value /= m_factor; #endif // __WXMSW__ wxASSERT_MSG(value <= m_maximum, wxT("invalid progress value")); - m_gauge->SetValue(value); + if (m_gauge) + m_gauge->SetValue(value); UpdateMessage(newmsg); @@ -588,10 +592,10 @@ bool ProgressDialog::Pulse(const wxString &newmsg, bool *skip) { if (!DoBeforeUpdate(skip)) return false; - wxCHECK_MSG(m_gauge, false, "dialog should be fully created"); + wxCHECK_MSG(m_msg || m_gauge, false, "dialog should be fully created"); // show a bit of progress - m_gauge->Pulse(); + if (m_gauge) m_gauge->Pulse(); UpdateMessage(newmsg); @@ -732,6 +736,8 @@ void ProgressDialog::OnCancel(wxCommandEvent &event) DisableAbort(); DisableSkip(); + OnCancel(); + // save the time when the dialog was stopped m_timeStop = wxGetCurrentTime(); } @@ -756,6 +762,7 @@ void ProgressDialog::OnClose(wxCloseEvent &event) m_state = Canceled; DisableAbort(); DisableSkip(); + OnCancel(); m_timeStop = wxGetCurrentTime(); } diff --git a/src/slic3r/GUI/Widgets/ProgressDialog.hpp b/src/slic3r/GUI/Widgets/ProgressDialog.hpp index 83268c267d..f67f6b89b3 100644 --- a/src/slic3r/GUI/Widgets/ProgressDialog.hpp +++ b/src/slic3r/GUI/Widgets/ProgressDialog.hpp @@ -19,6 +19,7 @@ class WXDLLIMPEXP_FWD_CORE wxWindowDisabler; #define PROGRESSDIALOG_DEF_BK wxColour(255,255,255) #define PROGRESSDIALOG_GREY_700 wxColour(107,107,107) +#define wxPD_NO_PROGRESS 0x0100 namespace Slic3r { namespace GUI { @@ -51,6 +52,8 @@ public: virtual bool WasCancelled() const; virtual bool WasSkipped() const; + virtual void OnCancel() {}; + // Must provide overload to avoid hiding it (and warnings about it) virtual void Update() wxOVERRIDE { wxDialog::Update(); }