FIX: [STUDIO-3057] keep download state in file

Change-Id: I6685f014e9c6fe3bf2e33218cec68d188f8cbc72
This commit is contained in:
chunmao.guo 2023-06-06 16:30:46 +08:00 committed by Lane.Wei
parent 87386c817c
commit 75545c65cd
4 changed files with 153 additions and 119 deletions

View file

@ -259,7 +259,7 @@ std::pair<int, size_t> Slic3r::GUI::ImageGrid::HitTest(wxPoint const &pt)
if (!m_selecting) { if (!m_selecting) {
wxRect hover_rect{0, m_content_rect.GetHeight() - 40, m_content_rect.GetWidth(), 40}; wxRect hover_rect{0, m_content_rect.GetHeight() - 40, m_content_rect.GetWidth(), 40};
auto & file = m_file_sys->GetFile(index); auto & file = m_file_sys->GetFile(index);
int btn = file.IsDownload() && file.progress >= 0 ? 3 : 2; int btn = file.IsDownload() && file.DownloadProgress() >= 0 ? 3 : 2;
if (m_file_sys->GetFileType() == PrinterFileSystem::F_MODEL) { if (m_file_sys->GetFileType() == PrinterFileSystem::F_MODEL) {
btn = 3; btn = 3;
hover_rect.y -= 64; hover_rect.y -= 64;
@ -598,21 +598,22 @@ void Slic3r::GUI::ImageGrid::renderContent1(wxDC &dc, wxPoint const &pt, int ind
int states = 0; int states = 0;
// Draw download progress // Draw download progress
if (file.IsDownload()) { if (file.IsDownload()) {
if (file.progress == -1) { int progress = file.DownloadProgress();
if (progress == -1) {
secondAction = _L("Cancel"); secondAction = _L("Cancel");
nonHoverText = _L("Download waiting..."); nonHoverText = _L("Download waiting...");
} else if (file.progress < 0) { } else if (progress < 0) {
secondAction = _L("Retry"); secondAction = _L("Retry");
nonHoverText = _L("Download failed"); nonHoverText = _L("Download failed");
states = StateColor::Checked; states = StateColor::Checked;
} else if (file.progress >= 100) { } else if (progress >= 100) {
secondAction = _L("Play"); secondAction = _L("Play");
thirdAction = _L("Open Folder"); thirdAction = _L("Open Folder");
nonHoverText = _L("Download finished"); nonHoverText = _L("Download finished");
} else { } else {
secondAction = _L("Cancel"); secondAction = _L("Cancel");
nonHoverText = wxString::Format(_L("Downloading %d%%..."), file.progress); nonHoverText = wxString::Format(_L("Downloading %d%%..."), progress);
thirdAction = wxString::Format(L"%d%%...", file.progress); thirdAction = wxString::Format(L"%d%%...", progress);
} }
} }
if (m_file_sys->GetFileType() == PrinterFileSystem::F_MODEL) { if (m_file_sys->GetFileType() == PrinterFileSystem::F_MODEL) {

View file

@ -500,7 +500,8 @@ void MediaFilePanel::doAction(size_t index, int action)
Slic3r::PlateDataPtrs plate_data_list; Slic3r::PlateDataPtrs plate_data_list;
Slic3r::Semver file_version; Slic3r::Semver file_version;
std::istringstream is(data); 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)
|| plate_data_list.empty()) {
MessageDialog(this, MessageDialog(this,
_L("Failed to parse model infomations."), _L("Failed to parse model infomations."),
_L("Error"), wxOK).ShowModal(); _L("Error"), wxOK).ShowModal();
@ -523,8 +524,8 @@ void MediaFilePanel::doAction(size_t index, int action)
} }
if (index != -1) { if (index != -1) {
auto &file = fs->GetFile(index); auto &file = fs->GetFile(index);
if (file.IsDownload() && file.progress >= -1) { if (file.IsDownload() && file.DownloadProgress() >= -1) {
if (file.progress >= 100) { if (!file.local_path.empty()) {
if (!fs->DownloadCheckFile(index)) { if (!fs->DownloadCheckFile(index)) {
MessageDialog(this, MessageDialog(this,
wxString::Format(_L("File '%s' was lost! Please download it again."), from_u8(file.name)), wxString::Format(_L("File '%s' was lost! Please download it again."), from_u8(file.name)),
@ -549,8 +550,8 @@ void MediaFilePanel::doAction(size_t index, int action)
} else if (action == 2) { } else if (action == 2) {
if (index != -1) { if (index != -1) {
auto &file = fs->GetFile(index); auto &file = fs->GetFile(index);
if (file.IsDownload() && file.progress >= -1) { if (file.IsDownload() && file.DownloadProgress() >= -1) {
if (file.progress >= 100) { if (!file.local_path.empty()) {
if (!fs->DownloadCheckFile(index)) { if (!fs->DownloadCheckFile(index)) {
MessageDialog(this, MessageDialog(this,
wxString::Format(_L("File '%s' was lost! Please download it again."), from_u8(file.name)), wxString::Format(_L("File '%s' was lost! Please download it again."), from_u8(file.name)),
@ -558,12 +559,7 @@ void MediaFilePanel::doAction(size_t index, int action)
Refresh(); Refresh();
return; return;
} }
#ifdef __WIN32__ desktop_open_any_folder(file.local_path);
wxExecute(L"explorer.exe /select," + from_u8(file.local_path));
#elif __APPLE__
openFolderForFile(from_u8(file.local_path));
#else
#endif
} else if (fs->GetFileType() == PrinterFileSystem::F_MODEL) { } else if (fs->GetFileType() == PrinterFileSystem::F_MODEL) {
fs->DownloadCancel(index); fs->DownloadCancel(index);
} }

View file

@ -163,7 +163,7 @@ void PrinterFileSystem::ListAllFiles()
iter1->flags = iter2->flags; iter1->flags = iter2->flags;
if (!iter1->thumbnail.IsOk()) if (!iter1->thumbnail.IsOk())
iter1->flags &= ~FF_THUMNAIL; iter1->flags &= ~FF_THUMNAIL;
iter1->progress = iter2->progress; iter1->download = iter2->download;
iter1->local_path = iter2->local_path; iter1->local_path = iter2->local_path;
iter1->metadata = iter2->metadata; iter1->metadata = iter2->metadata;
} }
@ -173,10 +173,11 @@ void PrinterFileSystem::ListAllFiles()
} }
BuildGroups(); BuildGroups();
UpdateGroupSelect(); UpdateGroupSelect();
m_task_flags = 0;
m_status = Status::ListReady; m_status = Status::ListReady;
SendChangedEvent(EVT_STATUS_CHANGED, m_status); SendChangedEvent(EVT_STATUS_CHANGED, m_status);
SendChangedEvent(EVT_FILE_CHANGED); SendChangedEvent(EVT_FILE_CHANGED);
if ((m_task_flags & FF_DOWNLOAD) == 0)
DownloadNextFile();
return 0; return 0;
}); });
} }
@ -205,6 +206,16 @@ void PrinterFileSystem::DeleteFiles(size_t index)
DeleteFilesContinue(); DeleteFilesContinue();
} }
struct PrinterFileSystem::Download : Progress
{
size_t index;
std::string name;
std::string path;
std::string local_path;
boost::filesystem::ofstream ofs;
boost::uuids::detail::md5 boost_md5;
};
void PrinterFileSystem::DownloadFiles(size_t index, std::string const &path) void PrinterFileSystem::DownloadFiles(size_t index, std::string const &path)
{ {
if (index == (size_t) -1) { if (index == (size_t) -1) {
@ -212,10 +223,12 @@ void PrinterFileSystem::DownloadFiles(size_t index, std::string const &path)
for (size_t i = 0; i < m_file_list.size(); ++i) { for (size_t i = 0; i < m_file_list.size(); ++i) {
auto &file = m_file_list[i]; auto &file = m_file_list[i];
if ((file.flags & FF_SELECT) == 0) continue; if ((file.flags & FF_SELECT) == 0) continue;
if ((file.flags & FF_DOWNLOAD) != 0 && file.progress >= 0) continue; if ((file.flags & FF_DOWNLOAD) != 0 && file.DownloadProgress() >= -1) continue;
file.flags |= FF_DOWNLOAD; file.flags |= FF_DOWNLOAD;
file.progress = -1; std::shared_ptr<Download> download(new Download);
file.local_path = (boost::filesystem::path(path) / file.name).string(); download->progress = -1;
download->local_path = (boost::filesystem::path(path) / file.name).string();
file.download = download;
++n; ++n;
} }
if (n == 0) return; if (n == 0) return;
@ -223,11 +236,13 @@ void PrinterFileSystem::DownloadFiles(size_t index, std::string const &path)
if (index >= m_file_list.size()) if (index >= m_file_list.size())
return; return;
auto &file = m_file_list[index]; auto &file = m_file_list[index];
if ((file.flags & FF_DOWNLOAD) != 0 && file.progress >= 0) if ((file.flags & FF_DOWNLOAD) != 0 && file.DownloadProgress() >= -1)
return; return;
file.flags |= FF_DOWNLOAD; file.flags |= FF_DOWNLOAD;
file.progress = -1; std::shared_ptr<Download> download(new Download);
file.local_path = (boost::filesystem::path(path) / file.name).string(); download->progress = -1;
download->local_path = (boost::filesystem::path(path) / file.name).string();
file.download = download;
} }
if ((m_task_flags & FF_DOWNLOAD) == 0) if ((m_task_flags & FF_DOWNLOAD) == 0)
DownloadNextFile(); DownloadNextFile();
@ -237,12 +252,11 @@ void PrinterFileSystem::DownloadCheckFiles(std::string const &path)
{ {
for (size_t i = 0; i < m_file_list.size(); ++i) { for (size_t i = 0; i < m_file_list.size(); ++i) {
auto &file = m_file_list[i]; auto &file = m_file_list[i];
if ((file.flags & FF_DOWNLOAD) != 0 && file.progress >= 0) continue; if ((file.flags & FF_DOWNLOAD) != 0 && file.download) continue;
auto path2 = boost::filesystem::path(path) / file.name; auto path2 = boost::filesystem::path(path) / file.name;
boost::system::error_code ec; boost::system::error_code ec;
if (boost::filesystem::file_size(path2, ec) == file.size) { if (boost::filesystem::file_size(path2, ec) == file.size) {
file.flags |= FF_DOWNLOAD; file.flags |= FF_DOWNLOAD;
file.progress = 100;
file.local_path = path2.string(); file.local_path = path2.string();
} }
} }
@ -252,10 +266,10 @@ bool PrinterFileSystem::DownloadCheckFile(size_t index)
{ {
if (index >= m_file_list.size()) return false; if (index >= m_file_list.size()) return false;
auto &file = m_file_list[index]; auto &file = m_file_list[index];
if ((file.flags & FF_DOWNLOAD) == 0) return false; if ((file.flags & FF_DOWNLOAD) == 0 || file.local_path.empty())
return false;
if (!boost::filesystem::exists(file.local_path)) { if (!boost::filesystem::exists(file.local_path)) {
file.flags &= ~FF_DOWNLOAD; file.flags &= ~FF_DOWNLOAD;
file.progress = 0;
file.local_path.clear(); file.local_path.clear();
SendChangedEvent(EVT_DOWNLOAD, index, file.local_path); SendChangedEvent(EVT_DOWNLOAD, index, file.local_path);
return false; return false;
@ -268,11 +282,11 @@ void PrinterFileSystem::DownloadCancel(size_t index)
if (index == (size_t) -1) return; if (index == (size_t) -1) return;
if (index >= m_file_list.size()) return; if (index >= m_file_list.size()) return;
auto &file = m_file_list[index]; auto &file = m_file_list[index];
if ((file.flags & FF_DOWNLOAD) == 0) return; if ((file.flags & FF_DOWNLOAD) == 0 || !file.download) return;
if (file.progress >= 0) if (file.DownloadProgress() >= 0)
CancelRequest(m_download_seq); CancelRequest(m_download_seq);
else else
file.flags &= ~FF_DOWNLOAD; file.flags &= ~FF_DOWNLOAD, file.download.reset();
} }
void PrinterFileSystem::FetchModel(size_t index, std::function<void(int, std::string const &)> callback) void PrinterFileSystem::FetchModel(size_t index, std::function<void(int, std::string const &)> callback)
@ -296,20 +310,22 @@ void PrinterFileSystem::FetchModel(size_t index, std::function<void(int, std::st
req["paths"] = arr; req["paths"] = arr;
req["zip"] = true; req["zip"] = true;
m_task_flags |= FF_FETCH_MODEL; m_task_flags |= FF_FETCH_MODEL;
m_fetch_model_seq = SendRequest<File>( std::shared_ptr<std::string> file_data(new std::string());
m_fetch_model_seq = SendRequest<Void>(
SUB_FILE, req, SUB_FILE, req,
[](json const &resp, File &file, unsigned char const *data) -> int { [file_data](json const &resp, Void &, unsigned char const *data) -> int {
// in work thread, continue recv // in work thread, continue recv
// receive data // receive data
boost::uint32_t size = resp["size"]; boost::uint32_t size = resp["size"];
if (size > 0) { if (size > 0) {
file.local_path = std::string((char *) data, size); *file_data += std::string((char *) data, size);
} }
return 0; return 0;
}, },
[this, callback](int result, File const &file) { [this, file_data, callback](int result, Void const &) {
if (result == CONTINUE) return;
m_task_flags &= ~FF_FETCH_MODEL; m_task_flags &= ~FF_FETCH_MODEL;
callback(result, file.local_path); callback(result, *file_data);
}); });
} }
@ -326,6 +342,8 @@ size_t PrinterFileSystem::GetCount() const
return m_group_mode == G_YEAR ? m_group_year.size() : m_group_month.size(); return m_group_mode == G_YEAR ? m_group_year.size() : m_group_month.size();
} }
int PrinterFileSystem::File::DownloadProgress() const { return download ? download->progress : !local_path.empty() ? 100 : -2; }
std::string PrinterFileSystem::File::Title() const { return Metadata("Title", name); } std::string PrinterFileSystem::File::Title() const { return Metadata("Title", name); }
std::string PrinterFileSystem::File::Metadata(std::string const &key, std::string const &dflt) const std::string PrinterFileSystem::File::Metadata(std::string const &key, std::string const &dflt) const
@ -558,12 +576,13 @@ void PrinterFileSystem::DeleteFilesContinue()
req["paths"] = arr; req["paths"] = arr;
} }
m_task_flags |= FF_DELETED; m_task_flags |= FF_DELETED;
auto type = std::make_pair(m_file_type, m_file_storage);
SendRequest<Void>( SendRequest<Void>(
FILE_DEL, req, nullptr, FILE_DEL, req, nullptr,
[indexes, names = paths.empty() ? names : paths, bypath = !paths.empty(), this](int, Void const &) { [indexes, type, names = paths.empty() ? names : paths, bypath = !paths.empty(), this](int, Void const &) {
// TODO: // TODO:
for (size_t i = indexes.size() - 1; i != size_t(-1); --i) for (size_t i = indexes.size() - 1; i != size_t(-1); --i)
FileRemoved(indexes[i], names[i], bypath); FileRemoved(type, indexes[i], names[i], bypath);
SendChangedEvent(EVT_FILE_CHANGED, indexes.size()); SendChangedEvent(EVT_FILE_CHANGED, indexes.size());
DeleteFilesContinue(); DeleteFilesContinue();
}); });
@ -573,7 +592,7 @@ void PrinterFileSystem::DownloadNextFile()
{ {
size_t index = size_t(-1); size_t index = size_t(-1);
for (size_t i = 0; i < m_file_list.size(); ++i) { for (size_t i = 0; i < m_file_list.size(); ++i) {
if ((m_file_list[i].flags & FF_DOWNLOAD) != 0 && m_file_list[i].progress == -1) { if (m_file_list[i].IsDownload() && m_file_list[i].DownloadProgress() == -1) {
index = i; index = i;
break; break;
} }
@ -581,43 +600,38 @@ void PrinterFileSystem::DownloadNextFile()
m_task_flags &= ~FF_DOWNLOAD; m_task_flags &= ~FF_DOWNLOAD;
if (index >= m_file_list.size()) if (index >= m_file_list.size())
return; return;
auto &file = m_file_list[index];
json req; json req;
if (m_file_list[index].path.empty()) if (file.path.empty())
req["file"] = m_file_list[index].name; req["file"] = file.name;
else else
req["path"] = m_file_list[index].path; req["path"] = file.path;
m_file_list[index].progress = 0;
SendChangedEvent(EVT_DOWNLOAD, index, m_file_list[index].name); SendChangedEvent(EVT_DOWNLOAD, index, m_file_list[index].name);
struct Download std::shared_ptr<Download> download(m_file_list[index].download);
{
size_t index;
std::string name;
std::string path;
std::string local_path;
boost::filesystem::ofstream ofs;
boost::uuids::detail::md5 boost_md5;
};
std::shared_ptr<Download> download(new Download);
download->index = index; download->index = index;
download->name = m_file_list[index].name; download->name = file.name;
download->path = m_file_list[index].path; download->path = file.path;
download->local_path = m_file_list[index].local_path;
m_task_flags |= FF_DOWNLOAD; m_task_flags |= FF_DOWNLOAD;
m_download_seq = SendRequest<Progress>( m_download_seq = SendRequest<Progress>(
FILE_DOWNLOAD, req, FILE_DOWNLOAD, req,
[download](json const &resp, Progress &prog, unsigned char const *data) -> int { [download](json const &resp, Progress &prog, unsigned char const *data) -> int {
// in work thread, continue recv // in work thread, continue recv
size_t size = resp["size"]; size_t size = resp.value("size", 0);
prog.size = resp["offset"]; prog.size = resp["offset"];
prog.total = resp["total"]; prog.total = resp["total"];
if (prog.size == 0) { if (prog.size == 0) {
download->ofs.open(download->local_path, std::ios::binary); download->ofs.open(download->local_path, std::ios::binary);
if (!download->ofs) return FILE_OPEN_ERR; if (!download->ofs) return FILE_OPEN_ERR;
} }
if (download->total && (download->size != prog.size || download->total != prog.total)) {
wxLogWarning("PrinterFileSystem::DownloadNextFile data error: %d != %d\n", download->size, download->size);
}
// receive data // receive data
download->ofs.write((char const *) data, size); download->ofs.write((char const *) data, size);
download->boost_md5.process_bytes(data, size); download->boost_md5.process_bytes(data, size);
prog.size += size; prog.size += size;
download->total = prog.total;
download->size = prog.size;
if (prog.size < prog.total) { return 0; } if (prog.size < prog.total) { return 0; }
download->ofs.close(); download->ofs.close();
int result = 0; int result = 0;
@ -645,19 +659,28 @@ void PrinterFileSystem::DownloadNextFile()
} }
return result; return result;
}, },
[this, download](int result, Progress const &data) { [this, download, type = std::make_pair(m_file_type, m_file_storage)](int result, Progress const &data) {
if (download->index != size_t(-1)) int progress = data.total ? data.size * 100 / data.total : 0;
download->index = FindFile(download->index, download->path.empty() ? download->name : download->path, !download->path.empty()); if (result == CONTINUE) {
if (download->progress == progress)
return;
}
download->progress = progress;
if (download->index != size_t(-1)) { if (download->index != size_t(-1)) {
int progress = data.size * 100 / data.total; auto file_index = FindFile(type, download->index, download->path.empty() ? download->name : download->path, !download->path.empty());
auto & file = m_file_list[download->index]; download->index = file_index.second;
if (result == ERROR_CANCEL) if (download->index != size_t(-1)) {
progress = -1, file.flags &= ~FF_DOWNLOAD; auto &file = file_index.first[download->index];
else if (result != CONTINUE && result != SUCCESS) if (result == CONTINUE)
progress = -2; ;
if (file.progress != progress) { else if (result == SUCCESS)
file.progress = progress; file.download.reset(), file.local_path = download->local_path;
SendChangedEvent(EVT_DOWNLOAD, download->index, file.local_path, result); else if (result == ERROR_CANCEL)
file.download.reset(), file.flags &= ~FF_DOWNLOAD;
else // FAILED
file.download.reset();
if (&file_index.first == &m_file_list)
SendChangedEvent(EVT_DOWNLOAD, download->index, file.local_path, result);
} }
} }
if (result != CONTINUE) DownloadNextFile(); if (result != CONTINUE) DownloadNextFile();
@ -875,51 +898,56 @@ void PrinterFileSystem::UpdateFocusThumbnail2(std::shared_ptr<std::vector<File>>
}); });
} }
size_t PrinterFileSystem::FindFile(size_t index, std::string const &name, bool by_path) std::pair<PrinterFileSystem::FileList &, size_t> PrinterFileSystem::FindFile(std::pair<FileType, std::string> type, size_t index, std::string const &name, bool by_path)
{ {
if (index >= m_file_list.size() || (by_path ? m_file_list[index].path : m_file_list[index].name) != name) { FileList & file_list = type == std::make_pair(m_file_type, m_file_storage) ?
auto iter = std::find_if(m_file_list.begin(), m_file_list.end(), m_file_list :
m_file_list_cache[type];
if (index >= file_list.size() || (by_path ? file_list[index].path : file_list[index].name) != name) {
auto iter = std::find_if(m_file_list.begin(), file_list.end(),
[name, by_path](File &f) { return (by_path ? f.path : f.name) == name; }); [name, by_path](File &f) { return (by_path ? f.path : f.name) == name; });
if (iter == m_file_list.end()) return -1; if (iter == m_file_list.end()) return {file_list, -1};
index = std::distance(m_file_list.begin(), iter); index = std::distance(m_file_list.begin(), iter);
} }
return index; return {file_list, index};
} }
void PrinterFileSystem::FileRemoved(size_t index, std::string const &name, bool by_path) void PrinterFileSystem::FileRemoved(std::pair<FileType, std::string> type, size_t index, std::string const &name, bool by_path)
{ {
index = FindFile(index, name, by_path); auto file_index = FindFile(type, index, name, by_path);
if (index == size_t(-1)) if (file_index.second == size_t(-1))
return; return;
auto removeFromGroup = [](std::vector<size_t> &group, size_t index, int total) { if (&file_index.first == &m_file_list) {
for (auto iter = group.begin(); iter != group.end(); ++iter) { auto removeFromGroup = [](std::vector<size_t> &group, size_t index, int total) {
size_t index2 = -1; for (auto iter = group.begin(); iter != group.end(); ++iter) {
if (*iter < index) continue; size_t index2 = -1;
if (*iter == index) { if (*iter < index) continue;
auto iter2 = iter + 1; if (*iter == index) {
if (iter2 == group.end() ? index == total - 1 : *iter2 == index + 1) { auto iter2 = iter + 1;
index2 = std::distance(group.begin(), iter); if (iter2 == group.end() ? index == total - 1 : *iter2 == index + 1) {
index2 = std::distance(group.begin(), iter);
}
++iter;
} }
++iter; for (; iter != group.end(); ++iter) {
--*iter;
}
return index2;
} }
for (; iter != group.end(); ++iter) { return size_t(-1);
--*iter; };
size_t index2 = removeFromGroup(m_group_month, index, m_file_list.size());
if (index2 < m_group_month.size()) {
int index3 = removeFromGroup(m_group_year, index, m_group_month.size());
if (index3 < m_group_year.size()) {
m_group_year.erase(m_group_year.begin() + index3);
if (m_group_mode == G_YEAR)
m_group_flags.erase(m_group_flags.begin() + index2);
} }
return index2; m_group_month.erase(m_group_month.begin() + index2);
} if (m_group_mode == G_MONTH)
return size_t(-1);
};
size_t index2 = removeFromGroup(m_group_month, index, m_file_list.size());
if (index2 < m_group_month.size()) {
int index3 = removeFromGroup(m_group_year, index, m_group_month.size());
if (index3 < m_group_year.size()) {
m_group_year.erase(m_group_year.begin() + index3);
if (m_group_mode == G_YEAR)
m_group_flags.erase(m_group_flags.begin() + index2); m_group_flags.erase(m_group_flags.begin() + index2);
} }
m_group_month.erase(m_group_month.begin() + index2);
if (m_group_mode == G_MONTH)
m_group_flags.erase(m_group_flags.begin() + index2);
} }
m_file_list.erase(m_file_list.begin() + index); m_file_list.erase(m_file_list.begin() + index);
} }
@ -996,12 +1024,13 @@ void PrinterFileSystem::CancelRequests(std::vector<boost::uint32_t> const &seqs)
for (auto seq : seqs) for (auto seq : seqs)
arr.push_back(seq); arr.push_back(seq);
req["tasks"] = arr; req["tasks"] = arr;
SendRequest(TASK_CANCEL, req, [this](int result, json const &resp, unsigned char const *) { SendRequest(TASK_CANCEL, req, [this](int result, json const &resp, unsigned char const *) -> int {
if (result != 0) return; if (result != 0) return result;
json tasks = resp["tasks"]; json tasks = resp["tasks"];
std::vector<boost::uint32_t> seqs; std::vector<boost::uint32_t> seqs;
for (auto &f : tasks) seqs.push_back(f); for (auto &f : tasks) seqs.push_back(f);
CancelRequests2(seqs); CancelRequests2(seqs);
return 0;
}); });
} }
@ -1118,7 +1147,12 @@ void PrinterFileSystem::HandleResponse(boost::unique_lock<boost::mutex> &l, Bamb
if (size_t(seq) >= m_callbacks.size()) return; if (size_t(seq) >= m_callbacks.size()) return;
auto c = m_callbacks[seq]; auto c = m_callbacks[seq];
if (c == nullptr) return; if (c == nullptr) return;
seq += m_sequence;
l.unlock();
result = c(result, resp, json_end);
l.lock();
if (result != CONTINUE) { if (result != CONTINUE) {
seq -= m_sequence;
m_callbacks[seq] = callback_t2(); m_callbacks[seq] = callback_t2();
if (seq == 0) { if (seq == 0) {
while (!m_callbacks.empty() && m_callbacks.front() == nullptr) { while (!m_callbacks.empty() && m_callbacks.front() == nullptr) {
@ -1127,9 +1161,6 @@ void PrinterFileSystem::HandleResponse(boost::unique_lock<boost::mutex> &l, Bamb
} }
} }
} }
l.unlock();
c(result, resp, json_end);
l.lock();
} }
} }

View file

@ -94,6 +94,15 @@ public:
FF_THUMNAIL_RETRY = 0x100, // Thumbnail need retry FF_THUMNAIL_RETRY = 0x100, // Thumbnail need retry
}; };
struct Progress
{
wxInt64 size = 0;
wxInt64 total = 0;
int progress = 0;
};
struct Download;
struct File struct File
{ {
std::string name; std::string name;
@ -102,12 +111,13 @@ public:
boost::uint64_t size = 0; boost::uint64_t size = 0;
int flags = 0; int flags = 0;
wxBitmap thumbnail; wxBitmap thumbnail;
int progress = -1; // -1: waiting std::shared_ptr<Download> download;
std::string local_path; std::string local_path;
std::map<std::string, std::string> metadata; std::map<std::string, std::string> metadata;
bool IsSelect() const { return flags & FF_SELECT; } bool IsSelect() const { return flags & FF_SELECT; }
bool IsDownload() const { return flags & FF_DOWNLOAD; } bool IsDownload() const { return flags & FF_DOWNLOAD; }
int DownloadProgress() const;
std::string Title() const; std::string Title() const;
std::string Metadata(std::string const &key, std::string const &dflt) const; std::string Metadata(std::string const &key, std::string const &dflt) const;
@ -118,12 +128,6 @@ public:
typedef std::vector<File> FileList; typedef std::vector<File> FileList;
struct Progress
{
wxInt64 size;
wxInt64 total;
};
void ListAllFiles(); void ListAllFiles();
void DeleteFiles(size_t index); void DeleteFiles(size_t index);
@ -194,9 +198,9 @@ private:
void UpdateFocusThumbnail2(std::shared_ptr<std::vector<File>> files, int type); void UpdateFocusThumbnail2(std::shared_ptr<std::vector<File>> files, int type);
void FileRemoved(size_t index, std::string const &name, bool by_path); void FileRemoved(std::pair<FileType, std::string> type, size_t index, std::string const &name, bool by_path);
size_t FindFile(size_t index, std::string const &name, bool by_path); std::pair<FileList &, size_t> FindFile(std::pair<FileType, std::string> type, size_t index, std::string const &name, bool by_path);
void SendChangedEvent(wxEventType type, size_t index = (size_t)-1, std::string const &str = {}, long extra = 0); void SendChangedEvent(wxEventType type, size_t index = (size_t)-1, std::string const &str = {}, long extra = 0);
@ -207,12 +211,12 @@ private:
typedef std::function<void(int, json const & resp)> callback_t; typedef std::function<void(int, json const & resp)> callback_t;
typedef std::function<void(int, json const &resp, unsigned char const *data)> callback_t2; typedef std::function<int(int, json const &resp, unsigned char const *data)> callback_t2;
template <typename T> template <typename T>
boost::uint32_t SendRequest(int type, json const& req, Translator<T> const& translator, Callback<T> const& callback) boost::uint32_t SendRequest(int type, json const& req, Translator<T> const& translator, Callback<T> const& callback)
{ {
auto c = [translator, callback, this](int result, json const &resp, unsigned char const *data) auto c = [translator, callback, this](int result, json const &resp, unsigned char const *data) -> int
{ {
T t; T t;
if (result == 0 || result == CONTINUE) { if (result == 0 || result == CONTINUE) {
@ -225,6 +229,7 @@ private:
} }
} }
PostCallback<T>(callback, result, t); PostCallback<T>(callback, result, t);
return result;
}; };
return SendRequest(type, req, c); return SendRequest(type, req, c);
} }
@ -234,7 +239,7 @@ private:
template<typename T> template<typename T>
void InstallNotify(int type, Translator<T> const& translator, Applier<T> const& applier) void InstallNotify(int type, Translator<T> const& translator, Applier<T> const& applier)
{ {
auto c = [translator, applier, this](int result, json const &resp, unsigned char const *data) auto c = [translator, applier, this](int result, json const &resp, unsigned char const *data) -> int
{ {
T t; T t;
if (result == 0 || result == CONTINUE) { if (result == 0 || result == CONTINUE) {
@ -251,6 +256,7 @@ private:
applier(t); applier(t);
}, 0, t); }, 0, t);
} }
return result;
}; };
InstallNotify(type, c); InstallNotify(type, c);
} }