ENH: [STUDIO-3151] Optimize scoring entry 2

Jira: 3151

Change-Id: I3a3a9d53f9557a93f02c44af3906b2e9f0761baf
This commit is contained in:
maosheng.wei 2023-09-08 20:33:33 +08:00 committed by Lane.Wei
parent ad9fa81b01
commit efb227af03
6 changed files with 447 additions and 199 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -17,6 +17,8 @@
#include "RecenterDialog.hpp" #include "RecenterDialog.hpp"
#include "CalibUtils.hpp" #include "CalibUtils.hpp"
#include <slic3r/GUI/Widgets/ProgressDialog.hpp> #include <slic3r/GUI/Widgets/ProgressDialog.hpp>
#include <wx/sstream.h>
#include <wx/zstream.h>
namespace Slic3r { namespace GUI { namespace Slic3r { namespace GUI {
@ -86,6 +88,8 @@ static std::vector<std::string> message_containing_done{
"12FF 8007" "12FF 8007"
}; };
static wxImage fail_image;
/* size */ /* size */
#define PAGE_TITLE_HEIGHT FromDIP(36) #define PAGE_TITLE_HEIGHT FromDIP(36)
@ -465,6 +469,8 @@ void PrintingTaskPanel::create_panel(wxWindow* parent)
ScalableBitmap dark_star = ScalableBitmap(nullptr, "score_star_dark", 26); ScalableBitmap dark_star = ScalableBitmap(nullptr, "score_star_dark", 26);
m_score_star[k]->SetBitmap(dark_star.bmp()); m_score_star[k]->SetBitmap(dark_star.bmp());
} }
m_star_count_dirty = true;
m_button_market_scoring->Enable(true);
}); });
static_score_star_sizer->Add(m_score_star[i], 0, wxEXPAND | wxLEFT, FromDIP(10)); static_score_star_sizer->Add(m_score_star[i], 0, wxEXPAND | wxLEFT, FromDIP(10));
} }
@ -473,13 +479,14 @@ void PrintingTaskPanel::create_panel(wxWindow* parent)
std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered), std::pair<wxColour, int>(AMS_CONTROL_BRAND_COLOUR, StateColor::Normal)); std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered), std::pair<wxColour, int>(AMS_CONTROL_BRAND_COLOUR, StateColor::Normal));
StateColor btn_bd_green(std::pair<wxColour, int>(AMS_CONTROL_WHITE_COLOUR, StateColor::Disabled), std::pair<wxColour, int>(AMS_CONTROL_BRAND_COLOUR, StateColor::Enabled)); StateColor btn_bd_green(std::pair<wxColour, int>(AMS_CONTROL_WHITE_COLOUR, StateColor::Disabled), std::pair<wxColour, int>(AMS_CONTROL_BRAND_COLOUR, StateColor::Enabled));
m_button_market_scoring = new Button(m_score_subtask_info, _L("Immediately score")); m_button_market_scoring = new Button(m_score_subtask_info, _L("Rating"));
m_button_market_scoring->SetBackgroundColor(btn_bg_green); m_button_market_scoring->SetBackgroundColor(btn_bg_green);
m_button_market_scoring->SetBorderColor(btn_bd_green); m_button_market_scoring->SetBorderColor(btn_bd_green);
m_button_market_scoring->SetTextColor(wxColour("#FFFFFE")); m_button_market_scoring->SetTextColor(wxColour("#FFFFFE"));
m_button_market_scoring->SetSize(wxSize(FromDIP(128), FromDIP(26))); m_button_market_scoring->SetSize(wxSize(FromDIP(128), FromDIP(26)));
m_button_market_scoring->SetMinSize(wxSize(-1, FromDIP(26))); m_button_market_scoring->SetMinSize(wxSize(-1, FromDIP(26)));
m_button_market_scoring->SetCornerRadius(FromDIP(13)); m_button_market_scoring->SetCornerRadius(FromDIP(13));
m_button_market_scoring->Enable(false);
static_score_star_sizer->Add(0, 0, 1, wxEXPAND, 0); static_score_star_sizer->Add(0, 0, 1, wxEXPAND, 0);
static_score_star_sizer->Add(m_button_market_scoring, 0, wxEXPAND | wxRIGHT, FromDIP(10)); static_score_star_sizer->Add(m_button_market_scoring, 0, wxEXPAND | wxRIGHT, FromDIP(10));
@ -681,16 +688,33 @@ void PrintingTaskPanel::show_profile_info(bool show, wxString profile /*= wxEmpt
} }
} }
void PrintingTaskPanel::market_scoring_show() { void PrintingTaskPanel::market_scoring_show()
{
m_score_staticline->Show(); m_score_staticline->Show();
m_score_subtask_info->Show(); m_score_subtask_info->Show();
} }
void PrintingTaskPanel::market_scoring_hide() { void PrintingTaskPanel::market_scoring_hide()
{
m_score_staticline->Hide(); m_score_staticline->Hide();
m_score_subtask_info->Hide(); m_score_subtask_info->Hide();
} }
void PrintingTaskPanel::set_star_count(int star_count)
{
m_star_count = star_count;
for (int i = 0; i < m_score_star.size(); ++i) {
if (i < star_count) {
ScalableBitmap light_star = ScalableBitmap(nullptr, "score_star_light", 26);
m_score_star[i]->SetBitmap(light_star.bmp());
} else {
ScalableBitmap dark_star = ScalableBitmap(nullptr, "score_star_dark", 26);
m_score_star[i]->SetBitmap(dark_star.bmp());
}
}
}
StatusBasePanel::StatusBasePanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, const wxString &name) StatusBasePanel::StatusBasePanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, const wxString &name)
: wxScrolledWindow(parent, id, pos, size, wxHSCROLL | wxVSCROLL) : wxScrolledWindow(parent, id, pos, size, wxHSCROLL | wxVSCROLL)
{ {
@ -1519,7 +1543,7 @@ StatusPanel::StatusPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, co
obj = nullptr; obj = nullptr;
m_score_data = new ScoreData; m_score_data = new ScoreData;
m_score_data->job_id = -1; m_score_data->rating_id = -1;
/* set default values */ /* set default values */
m_switch_lamp->SetValue(false); m_switch_lamp->SetValue(false);
m_switch_printing_fan->SetValue(false); m_switch_printing_fan->SetValue(false);
@ -1660,27 +1684,59 @@ void StatusPanel::init_scaled_buttons()
} }
void StatusPanel::on_market_scoring(wxCommandEvent &event) { void StatusPanel::on_market_scoring(wxCommandEvent &event) {
if (obj && obj->get_modeltask() && obj->get_modeltask()->design_id > 0) { if (obj && obj->get_modeltask() && obj->get_modeltask()->design_id > 0 && m_rating_result.contains("id")) { // model is mall model and has rating_id
if (m_score_data && m_score_data->job_id == obj->get_modeltask()->job_id) {
if (m_score_data && m_score_data->rating_id == m_rating_result["id"].get<unsigned int>()) { // current score data for model is same as mall model
ScoreDialog m_score_dlg(this, m_score_data); ScoreDialog m_score_dlg(this, m_score_data);
int ret = m_score_dlg.ShowModal(); int ret = m_score_dlg.ShowModal();
if (ret == wxID_OK) { if (ret == wxID_OK) {
m_score_data->job_id = -1; m_score_data->rating_id = -1;
return; return;
} }
if (m_score_data != nullptr) { delete m_score_data; } if (m_score_data != nullptr) {
m_score_data = new ScoreData(m_score_dlg.get_score_data()); delete m_score_data;
m_score_data = nullptr;
}
m_score_data = new ScoreData(m_score_dlg.get_score_data()); // when user do not submit score, store the data for next opening the score dialog
m_project_task_panel->set_star_count(m_score_data->star_count);
} else { } else {
ScoreDialog m_score_dlg(this, obj->get_modeltask()->design_id, obj->get_modeltask()->job_id, obj->get_modeltask()->model_id, obj->get_modeltask()->profile_id, //to do: if user has rated the model, show the comment on the dialog
m_project_task_panel->get_star_count()); int star_count = 0;
if (m_rating_result.contains("content"))
star_count = m_project_task_panel->get_star_count_dirty() ? m_project_task_panel->get_star_count() : m_rating_result["score"].get<int>();
bool success_print = true;
if (m_rating_result.contains("successPrinted"))
success_print = m_rating_result["successPrinted"].get<bool>();
ScoreDialog m_score_dlg(this, obj->get_modeltask()->design_id, obj->get_modeltask()->model_id, obj->get_modeltask()->profile_id,
m_rating_result["id"].get<unsigned int>(), success_print, star_count);
if (m_rating_result.contains("content")) {
std::string comment = m_rating_result["content"].get<std::string>();
if (!comment.empty()) {
m_score_dlg.set_comment(comment);
}
}
if (m_rating_result.contains("images")) {
std::vector<std::string> images_json_array;
images_json_array = m_rating_result["images"].get<std::vector<std::string>>();
m_score_dlg.set_cloud_bitmap(images_json_array);
}
int ret = m_score_dlg.ShowModal(); int ret = m_score_dlg.ShowModal();
if (ret == wxID_OK) { if (ret == wxID_OK) {
m_score_data->job_id = -1; m_score_data->rating_id = -1;
return; return;
} }
if (m_score_data != nullptr) { delete m_score_data; } if (m_score_data != nullptr) {
delete m_score_data;
m_score_data = nullptr;
}
m_score_data = new ScoreData(m_score_dlg.get_score_data()); m_score_data = new ScoreData(m_score_dlg.get_score_data());
m_project_task_panel->set_star_count(m_score_data->star_count);
} }
@ -2717,31 +2773,54 @@ void StatusPanel::update_subtask(MachineObject *obj)
m_project_task_panel->enable_abort_button(false); m_project_task_panel->enable_abort_button(false);
m_project_task_panel->enable_pause_resume_button(false, "resume_disable"); m_project_task_panel->enable_pause_resume_button(false, "resume_disable");
if (wxGetApp().has_model_mall()) { if (wxGetApp().has_model_mall()) {
//determine whether the model is mall model
bool is_market_task = obj->get_modeltask() && obj->get_modeltask()->design_id > 0; bool is_market_task = obj->get_modeltask() && obj->get_modeltask()->design_id > 0;
if (is_market_task) { if (is_market_task) {
m_project_task_panel->market_scoring_show(); NetworkAgent *agent = wxGetApp().getAgent();
BOOST_LOG_TRIVIAL(info) << "SHOW_SCORE_BTU: design_id [" << obj->get_modeltask()->design_id << "] print_finish [" << m_print_finish << "]"; if (agent && IsShownOnScreen()) {
if (!m_print_finish && IsShownOnScreen()) {
m_print_finish = true; int job_id = obj->get_modeltask()->job_id;
/*int job_id = obj->get_modeltask()->job_id; boost::thread([this, agent, job_id] {
if (wxGetApp().app_config->get("not_show_score_dialog") != "1" && rated_model_id.find(job_id) == rated_model_id.end()) { try {
MessageDialog dlg(this, _L("Please give a score for your favorite Bambu Market model."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Score"), std::string rating_result;
wxYES_NO | wxYES_DEFAULT | wxCENTRE); unsigned int http_code = 0;
dlg.show_dsa_button(); std::string http_error;
int old_design_id = obj->get_modeltask()->design_id; int rating_id = -1;
auto res = dlg.ShowModal(); int res = agent->get_model_mall_rating_result(job_id, rating_result, http_code, http_error);
if (dlg.get_checkbox_state()) { wxGetApp().app_config->set("not_show_score_dialog", "1"); } if (0 == res) {
if (res == wxID_YES) { market_model_scoring_page(old_design_id); } m_rating_result = json::parse(rating_result);
rated_model_id.insert(job_id); if (m_rating_result.contains("id")) {
BOOST_LOG_TRIVIAL(info) << "SHOW_SCORE_DLG: design_id [" << old_design_id << "] print_finish [" << m_print_finish << "] not_show [" rating_id = m_rating_result["id"].get<unsigned int>();
<< wxGetApp().app_config->get("not_show_score_dialog") << "] job_id [" << job_id << "]"; m_project_task_panel->market_scoring_show();
}*/ BOOST_LOG_TRIVIAL(info) << "show scoring page";
bool is_update = model_score_is_update();
// this mall model has score, user do not click star, Initialize scores only once per print startup program
if (is_update ||
(!m_project_task_panel->get_star_count_dirty() && !m_print_finish && IsShownOnScreen() && m_rating_result.contains("score"))) {
int star_count = m_rating_result["score"].get<int>();
m_project_task_panel->set_star_count(star_count);
BOOST_LOG_TRIVIAL(info) << "Initialize scores";
m_project_task_panel->set_star_count_dirty(true);
m_print_finish = true;
if (0 != star_count) { m_project_task_panel->get_market_scoring_button()->Enable(true); }
}
}
}
} catch (...) {
m_project_task_panel->market_scoring_hide();
BOOST_LOG_TRIVIAL(info) << "get mall model rating id failed and hide scoring page";
}
});
} }
} else { BOOST_LOG_TRIVIAL(info) << "SHOW_SCORE_BTU: design_id [" << obj->get_modeltask()->design_id << "] print_finish [" << m_print_finish << "]";
} else { // model is not mall model. hide scoring page
m_project_task_panel->market_scoring_hide(); m_project_task_panel->market_scoring_hide();
} }
} else { // have no model mall, hide scoring page
m_project_task_panel->market_scoring_hide();
} }
} else { } else { // model printing is not finished, hide scoring page
m_project_task_panel->enable_abort_button(true); m_project_task_panel->enable_abort_button(true);
m_project_task_panel->market_scoring_hide(); m_project_task_panel->market_scoring_hide();
if (m_print_finish) { if (m_print_finish) {
@ -2787,6 +2866,18 @@ void StatusPanel::update_subtask(MachineObject *obj)
this->Layout(); this->Layout();
} }
bool StatusPanel::model_score_is_update()
{
try {
if (m_last_result["id"] != m_rating_result["id"] || m_last_result["content"] != m_rating_result["content"] || m_last_result["images"] != m_rating_result["images"]) {
m_last_result = m_rating_result;
return true;
}
} catch (...) {}
return false;
}
void StatusPanel::update_cloud_subtask(MachineObject *obj) void StatusPanel::update_cloud_subtask(MachineObject *obj)
{ {
if (!obj) return; if (!obj) return;
@ -3931,36 +4022,19 @@ void StatusPanel::msw_rescale()
Layout(); Layout();
Refresh(); Refresh();
} }
static char *bbl_calc_md5_char(std::string &filename)
{
unsigned char digest[16];
MD5_CTX ctx;
MD5_Init(&ctx);
boost::filesystem::ifstream ifs(filename, std::ios::binary);
std::string buf(64 * 1024, 0);
const std::size_t & size = boost::filesystem::file_size(filename);
std::size_t left_size = size;
while (ifs) {
ifs.read(buf.data(), buf.size());
int read_bytes = ifs.gcount();
MD5_Update(&ctx, (unsigned char *) buf.data(), read_bytes);
}
MD5_Final(digest, &ctx);
char *md5_str = new char[33];
for (int j = 0; j < 16; j++) { sprintf(&md5_str[j * 2], "%02X", (unsigned int) digest[j]); }
md5_str[32] = '\0';
return md5_str;
}
ScoreDialog::ScoreDialog(wxWindow *parent,int design_id, int job_id, std::string model_id, int profile_id, int star_count) ScoreDialog::ScoreDialog(wxWindow *parent, int design_id, std::string model_id, int profile_id, int rating_id, bool success_printed, int star_count)
: DPIDialog(parent, wxID_ANY, wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Scoring"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX | wxRESIZE_BORDER) : DPIDialog(parent, wxID_ANY, _L("Rate the Print Profile"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX | wxRESIZE_BORDER)
, m_design_id(design_id) , m_design_id(design_id)
, m_job_id(job_id)
, m_model_id(model_id) , m_model_id(model_id)
, m_profile_id(profile_id) , m_profile_id(profile_id)
, m_star_count(star_count) , m_star_count(star_count)
, m_rating_id(rating_id)
, m_success_printed(success_printed)
, m_upload_status_code(StatusCode::CODE_NUMBER) , m_upload_status_code(StatusCode::CODE_NUMBER)
{ {
m_tocken.reset(new int(0));
wxBoxSizer *m_main_sizer = get_main_sizer(); wxBoxSizer *m_main_sizer = get_main_sizer();
this->SetSizer(m_main_sizer); this->SetSizer(m_main_sizer);
@ -3970,25 +4044,21 @@ ScoreDialog::ScoreDialog(wxWindow *parent,int design_id, int job_id, std::string
} }
ScoreDialog::ScoreDialog(wxWindow *parent, ScoreData *score_data) ScoreDialog::ScoreDialog(wxWindow *parent, ScoreData *score_data)
: DPIDialog(parent, wxID_ANY, wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Scoring"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX | wxRESIZE_BORDER) : DPIDialog(parent, wxID_ANY, _L("Rate the Print Profile"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX | wxRESIZE_BORDER)
, m_design_id(score_data->design_id) , m_design_id(score_data->design_id)
, m_job_id(score_data->job_id) , m_rating_id(score_data->rating_id)
, m_model_id(score_data->model_id) , m_model_id(score_data->model_id)
, m_profile_id(score_data->profile_id) , m_profile_id(score_data->profile_id)
, m_star_count(score_data->star_count) , m_star_count(score_data->star_count)
, m_success_printed(score_data->success_printed)
, m_upload_status_code(StatusCode::CODE_NUMBER) , m_upload_status_code(StatusCode::CODE_NUMBER)
{ {
wxBoxSizer *m_main_sizer = get_main_sizer(score_data->image,score_data->comment_text); m_tocken.reset(new int(0));
m_need_upload_images = score_data->need_upload_images;
m_image_url_paths = score_data->image_url_paths; wxBoxSizer *m_main_sizer = get_main_sizer(score_data->local_to_url_image, score_data->comment_text);
m_local_to_url_image = score_data->local_to_url_image;
for (auto image : m_image) { m_image_url_paths = score_data->image_url_paths;
wxString local_image_path = image.second.local_image_url;
if (m_need_upload_images.find(local_image_path) == m_need_upload_images.end()) {
image.second.is_uploaded = true;
}
}
this->SetSizer(m_main_sizer); this->SetSizer(m_main_sizer);
Fit(); Fit();
@ -4029,23 +4099,136 @@ void ScoreDialog::OnBitmapClicked(wxMouseEvent &event)
} }
void ScoreDialog::add_need_upload_imgs() { std::set <std::pair<wxStaticBitmap * ,wxString>> ScoreDialog::add_need_upload_imgs()
{
std::set<std::pair<wxStaticBitmap *, wxString>> need_upload_images;
for (auto bitmap : m_image) { for (auto bitmap : m_image) {
wxString local_image_path = bitmap.second.local_image_url;
if (!bitmap.second.is_uploaded) { if (!bitmap.second.is_uploaded) {
m_need_upload_images.insert(local_image_path); wxString &local_image_path = bitmap.second.local_image_url;
} else { if (!local_image_path.empty()) { need_upload_images.insert(std::make_pair(bitmap.first, local_image_path)); }
if (m_need_upload_images.find(local_image_path) != m_need_upload_images.end()) {
m_need_upload_images.erase(local_image_path);
}
} }
} }
return need_upload_images;
}
std::pair<wxStaticBitmap *, ScoreDialog::ImageMsg> ScoreDialog::create_local_thumbnail(wxString &local_path)
{
std::pair<wxStaticBitmap *, ImageMsg> bitmap_to_image_msg;
if (local_path.empty()) return bitmap_to_image_msg;
ImageMsg cur_image_msg;
cur_image_msg.local_image_url = local_path;
cur_image_msg.img_url_paths = "";
cur_image_msg.is_uploaded = false;
wxStaticBitmap *imageCtrl = new wxStaticBitmap(this, wxID_ANY, wxBitmap(wxImage(local_path, wxBITMAP_TYPE_ANY).Rescale(FromDIP(80), FromDIP(60))), wxDefaultPosition,
wxDefaultSize, 0);
imageCtrl->Bind(wxEVT_LEFT_DOWN, &ScoreDialog::OnBitmapClicked, this);
m_image_sizer->Add(create_broad_sizer(imageCtrl, cur_image_msg), 0, wxALL, 5);
bitmap_to_image_msg.first = imageCtrl;
bitmap_to_image_msg.second = cur_image_msg;
return bitmap_to_image_msg;
}
std::pair<wxStaticBitmap *, ScoreDialog::ImageMsg> ScoreDialog::create_oss_thumbnail(std::string &oss_path)
{
std::pair<wxStaticBitmap *, ImageMsg> bitmap_to_image_msg;
if (oss_path.empty()) return bitmap_to_image_msg;
ImageMsg cur_image_msg;
cur_image_msg.local_image_url = "";
cur_image_msg.img_url_paths = oss_path;
cur_image_msg.is_uploaded = true;
wxImage image(Slic3r::resources_dir() + "/images/oss_picture_loading.png", wxBITMAP_TYPE_ANY);
wxStaticBitmap *imageCtrl = new wxStaticBitmap(this, wxID_ANY, wxBitmap(image.Rescale(FromDIP(80), FromDIP(60))), wxDefaultPosition, wxDefaultSize, 0);
imageCtrl->Bind(wxEVT_LEFT_DOWN, &ScoreDialog::OnBitmapClicked, this);
Slic3r::Http http = Slic3r::Http::get(oss_path);
std::string suffix = oss_path.substr(oss_path.find_last_of(".") + 1);
http.header("accept", "image/" + suffix) //"image/" + suffix
.header("Accept-Encoding", "gzip")
.on_complete([this, imageCtrl, time = std::weak_ptr<int>(m_tocken)](std::string body, unsigned int status) {
if (time.expired()) return;
wxMemoryInputStream stream(body.data(), body.size());
wxImage success_image;
if (success_image.LoadFile(stream, wxBITMAP_TYPE_ANY)) {
CallAfter([this, success_image, imageCtrl]() { update_static_bitmap(imageCtrl, success_image); });
} else {
CallAfter([this, imageCtrl]() { update_static_bitmap(imageCtrl, fail_image); });
}
})
.on_error([this, imageCtrl, &oss_path](std::string body, std::string error, unsigned status) {
BOOST_LOG_TRIVIAL(info) << "load oss picture failed, oss path: " << oss_path << " status:" << status << " error:" << error;
CallAfter([this, imageCtrl]() { update_static_bitmap(imageCtrl, fail_image); });
}).perform();
m_image_sizer->Add(create_broad_sizer(imageCtrl, cur_image_msg), 0, wxALL, 5);
bitmap_to_image_msg.first = imageCtrl;
bitmap_to_image_msg.second = cur_image_msg;
return bitmap_to_image_msg;
}
void ScoreDialog::update_static_bitmap(wxStaticBitmap* static_bitmap, wxImage image)
{
static_bitmap->SetBitmap(wxBitmap(image.Rescale(FromDIP(80), FromDIP(60))));
Layout();
Fit();
//Refresh();
}
wxBoxSizer *ScoreDialog::create_broad_sizer(wxStaticBitmap *bitmap, ImageMsg& cur_image_msg)
{
// tb: top and bottom lr: left and right
auto m_image_tb_broad = new wxBoxSizer(wxVERTICAL);
auto line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
line_top->SetBackgroundColour(wxColour(0xA6, 0xa9, 0xAA));
m_image_tb_broad->Add(line_top, 0, wxEXPAND, 0);
cur_image_msg.image_broad.push_back(line_top);
line_top->Hide();
auto m_image_lr_broad = new wxBoxSizer(wxHORIZONTAL);
auto line_left = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(1, -1), wxTAB_TRAVERSAL);
line_left->SetBackgroundColour(wxColour(0xA6, 0xa9, 0xAA));
m_image_lr_broad->Add(line_left, 0, wxEXPAND, 0);
cur_image_msg.image_broad.push_back(line_left);
line_left->Hide();
m_image_lr_broad->Add(bitmap, 0, wxALL, 5);
auto line_right = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(1, -1), wxTAB_TRAVERSAL);
line_right->SetBackgroundColour(wxColour(0xA6, 0xa9, 0xAA));
m_image_lr_broad->Add(line_right, 0, wxEXPAND, 0);
m_image_tb_broad->Add(m_image_lr_broad, 0, wxEXPAND, 0);
cur_image_msg.image_broad.push_back(line_right);
line_right->Hide();
auto line_bottom = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
line_bottom->SetBackgroundColour(wxColour(0xA6, 0xa9, 0xAA));
m_image_tb_broad->Add(line_bottom, 0, wxEXPAND, 0);
cur_image_msg.image_broad.push_back(line_bottom);
line_bottom->Hide();
cur_image_msg.is_selected = false;
cur_image_msg.image_tb_broad = m_image_tb_broad;
return m_image_tb_broad;
} }
void ScoreDialog::init() { void ScoreDialog::init() {
SetBackgroundColour(*wxWHITE); SetBackgroundColour(*wxWHITE);
SetMinSize(wxSize(FromDIP(540), FromDIP(380))); SetMinSize(wxSize(FromDIP(540), FromDIP(380)));
fail_image = wxImage(Slic3r::resources_dir() + "/images/oss_picture_load_failed.png", wxBITMAP_TYPE_ANY);
// icon // icon
std::string icon_path = (boost::format("%1%/images/BambuStudio.ico") % resources_dir()).str(); std::string icon_path = (boost::format("%1%/images/BambuStudio.ico") % resources_dir()).str();
SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO)); SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
@ -4053,7 +4236,7 @@ void ScoreDialog::init() {
wxBoxSizer *ScoreDialog::get_score_sizer() { wxBoxSizer *ScoreDialog::get_score_sizer() {
wxBoxSizer *score_sizer = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *score_sizer = new wxBoxSizer(wxHORIZONTAL);
wxStaticText *static_score_text = new wxStaticText(this, wxID_ANY, _L("Scoring"), wxDefaultPosition, wxDefaultSize, 0); wxStaticText *static_score_text = new wxStaticText(this, wxID_ANY, _L("Rate"), wxDefaultPosition, wxDefaultSize, 0);
static_score_text->Wrap(-1); static_score_text->Wrap(-1);
score_sizer->Add(static_score_text, 1, wxEXPAND | wxLEFT, FromDIP(24)); score_sizer->Add(static_score_text, 1, wxEXPAND | wxLEFT, FromDIP(24));
score_sizer->Add(0, 0, 1, wxEXPAND, 0); score_sizer->Add(0, 0, 1, wxEXPAND, 0);
@ -4065,6 +4248,12 @@ wxBoxSizer *ScoreDialog::get_star_sizer()
wxBoxSizer *static_score_star_sizer = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *static_score_star_sizer = new wxBoxSizer(wxHORIZONTAL);
m_score_star.resize(5); m_score_star.resize(5);
for (int i = 0; i < m_score_star.size(); ++i) { for (int i = 0; i < m_score_star.size(); ++i) {
if (!m_success_printed && m_star_count > 3) {
m_star_count = 3;
warning_text->Show();
Layout();
Fit();
}
if (i < m_star_count) { if (i < m_star_count) {
m_score_star[i] = new ScalableButton(this, wxID_ANY, "score_star_light", wxEmptyString, wxSize(FromDIP(26), FromDIP(26)), wxDefaultPosition, m_score_star[i] = new ScalableButton(this, wxID_ANY, "score_star_light", wxEmptyString, wxSize(FromDIP(26), FromDIP(26)), wxDefaultPosition,
wxBU_EXACTFIT | wxNO_BORDER, true, 26); wxBU_EXACTFIT | wxNO_BORDER, true, 26);
@ -4073,6 +4262,16 @@ wxBoxSizer *ScoreDialog::get_star_sizer()
wxBU_EXACTFIT | wxNO_BORDER, true, 26); wxBU_EXACTFIT | wxNO_BORDER, true, 26);
m_score_star[i]->Bind(wxEVT_LEFT_DOWN, [this, i](auto &e) { m_score_star[i]->Bind(wxEVT_LEFT_DOWN, [this, i](auto &e) {
if (!m_success_printed && i >= 3) {
warning_text->Show();
Layout();
Fit();
return;
} else {
warning_text->Hide();
Layout();
Fit();
}
for (int j = 0; j < m_score_star.size(); ++j) { for (int j = 0; j < m_score_star.size(); ++j) {
ScalableBitmap light_star = ScalableBitmap(nullptr, "score_star_light", 26); ScalableBitmap light_star = ScalableBitmap(nullptr, "score_star_light", 26);
m_score_star[j]->SetBitmap(light_star.bmp()); m_score_star[j]->SetBitmap(light_star.bmp());
@ -4103,10 +4302,16 @@ wxBoxSizer* ScoreDialog::get_comment_text_sizer() {
void ScoreDialog::create_comment_text(const wxString& comment) { void ScoreDialog::create_comment_text(const wxString& comment) {
m_comment_text = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxSize(FromDIP(492), FromDIP(104)), wxTE_MULTILINE); m_comment_text = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxSize(FromDIP(492), FromDIP(104)), wxTE_MULTILINE);
m_comment_text->SetLabelText(comment); if (!comment.empty()) {
m_comment_text->SetValue(comment);
if (wxGetApp().dark_mode()) {
m_comment_text->SetForegroundColour(wxColor(*wxWHITE));
} else
m_comment_text->SetForegroundColour(wxColor(*wxBLACK));
}
m_comment_text->SetHint(_L("Rate this print")); m_comment_text->SetHint(_L("Rate this print"));
m_comment_text->SetBackgroundColour(*wxWHITE); m_comment_text->SetBackgroundColour(*wxWHITE);
m_comment_text->SetForegroundColour(wxColor("#BBBBBB")); //m_comment_text->SetForegroundColour(wxColor("#BBBBBB"));
m_comment_text->SetMinSize(wxSize(FromDIP(492), FromDIP(104))); m_comment_text->SetMinSize(wxSize(FromDIP(492), FromDIP(104)));
m_comment_text->Bind(wxEVT_SET_FOCUS, [this](auto &event) { m_comment_text->Bind(wxEVT_SET_FOCUS, [this](auto &event) {
@ -4140,13 +4345,14 @@ wxBoxSizer *ScoreDialog::get_photo_btn_sizer() {
m_add_photo->Bind(wxEVT_LEFT_DOWN, [this](auto &e) { m_add_photo->Bind(wxEVT_LEFT_DOWN, [this](auto &e) {
// add photo logic // add photo logic
wxFileDialog openFileDialog(this, "Select Images", "", "", "Image files (*.bmp;*.png;*.jpg)|*.bmp;*.png;*.jpg", wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE); wxFileDialog openFileDialog(this, "Select Images", "", "", "Image files (*.png;*.jpg)|*.png;*.jpg", wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
if (openFileDialog.ShowModal() == wxID_CANCEL) return; if (openFileDialog.ShowModal() == wxID_CANCEL) return;
wxArrayString filePaths; wxArrayString filePaths;
openFileDialog.GetPaths(filePaths); openFileDialog.GetPaths(filePaths);
wxArrayString filePaths_reduction; //wxArrayString filePaths_reduction;
std::vector<std::pair<wxString, std::string>> local_path;
for (int i = 0; i < filePaths.GetCount(); i++) { //It's ugly, but useful for (int i = 0; i < filePaths.GetCount(); i++) { //It's ugly, but useful
bool is_repeat = false; bool is_repeat = false;
for (auto image : m_image) { for (auto image : m_image) {
@ -4156,15 +4362,15 @@ wxBoxSizer *ScoreDialog::get_photo_btn_sizer() {
} }
} }
if (!is_repeat) { if (!is_repeat) {
filePaths_reduction.push_back(filePaths[i]); local_path.push_back(std::make_pair(filePaths[i], ""));
if (filePaths_reduction.size() + m_image.size() > m_photo_nums) { if (local_path.size() + m_image.size() > m_photo_nums) {
break; break;
} }
} }
} }
load_photo(filePaths_reduction); load_photo(local_path);
m_image_sizer->Layout(); m_image_sizer->Layout();
this->Fit(); this->Fit();
@ -4176,18 +4382,21 @@ wxBoxSizer *ScoreDialog::get_photo_btn_sizer() {
auto bitmap = *it; auto bitmap = *it;
m_image_sizer->Detach(m_image[bitmap].image_tb_broad); m_image_sizer->Detach(m_image[bitmap].image_tb_broad);
m_image[bitmap].image_tb_broad->DeleteWindows(); m_image[bitmap].image_tb_broad->DeleteWindows();
wxString local_image_path = m_image[bitmap].local_image_url;
if (m_need_upload_images.find(local_image_path) != m_need_upload_images.end()) { m_need_upload_images.erase(local_image_path); }
if (m_local_to_url_image.find(local_image_path) != m_local_to_url_image.end()) { m_local_to_url_image.erase(local_image_path); }
m_image.erase(bitmap); m_image.erase(bitmap);
it = m_selected_image_list.erase(it); it = m_selected_image_list.erase(it);
} }
m_image_url_paths.clear(); m_image_url_paths.clear();
for (auto local_to_url_image : m_local_to_url_image) { m_image_url_paths.push_back(local_to_url_image.second); } for (const std::pair<wxStaticBitmap *, ImageMsg> &bitmap : m_image) {
if (bitmap.second.is_uploaded) {
if (!bitmap.second.img_url_paths.empty()) {
m_image_url_paths.push_back(bitmap.second.img_url_paths);
}
}
}
m_delete_photo->Hide(); m_delete_photo->Hide();
m_image_sizer->Layout();
Layout(); Layout();
Fit();
}); });
return m_photo_sizer; return m_photo_sizer;
@ -4201,7 +4410,7 @@ wxBoxSizer *ScoreDialog::get_button_sizer()
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed), std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered), StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed), std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered),
std::pair<wxColour, int>(AMS_CONTROL_BRAND_COLOUR, StateColor::Normal)); std::pair<wxColour, int>(AMS_CONTROL_BRAND_COLOUR, StateColor::Normal));
m_button_ok = new Button(this, _L("OK")); m_button_ok = new Button(this, _L("Submit"));
m_button_ok->SetBackgroundColor(btn_bg_green); m_button_ok->SetBackgroundColor(btn_bg_green);
m_button_ok->SetBorderColor(*wxWHITE); m_button_ok->SetBorderColor(*wxWHITE);
m_button_ok->SetTextColor(wxColour(0xFFFFFE)); m_button_ok->SetTextColor(wxColour(0xFFFFFE));
@ -4220,14 +4429,14 @@ wxBoxSizer *ScoreDialog::get_button_sizer()
return; return;
} }
add_need_upload_imgs(); std::set<std::pair<wxStaticBitmap *, wxString>> need_upload_images = add_need_upload_imgs();
std::string comment = into_u8(m_comment_text->GetValue()); std::string comment = into_u8(m_comment_text->GetValue());
unsigned int http_code; unsigned int http_code;
std::string http_error; std::string http_error;
wxString error_info; wxString error_info;
if (!m_need_upload_images.empty()) { if (!need_upload_images.empty()) {
std::string config; std::string config;
int ret = wxGetApp().getAgent()->get_oss_config(config, wxGetApp().app_config->get_country_code(), http_code, http_error); int ret = wxGetApp().getAgent()->get_oss_config(config, wxGetApp().app_config->get_country_code(), http_code, http_error);
if (ret == -1) { if (ret == -1) {
@ -4235,42 +4444,48 @@ wxBoxSizer *ScoreDialog::get_button_sizer()
m_upload_status_code = StatusCode::UPLOAD_EXIST_ISSUE; m_upload_status_code = StatusCode::UPLOAD_EXIST_ISSUE;
} }
if (m_upload_status_code == StatusCode::UPLOAD_PROGRESS) { if (m_upload_status_code == StatusCode::UPLOAD_PROGRESS) {
int need_upload_nums = m_need_upload_images.size(); int need_upload_nums = need_upload_images.size();
int upload_nums = 0; int upload_nums = 0;
int upload_failed_nums = 0; int upload_failed_nums = 0;
ProgressDialog *progress_dialog = new ProgressDialog(_L("Upload Pictrues"), wxString("..."), need_upload_nums, this); ProgressDialog *progress_dialog = new ProgressDialog(_L("Upload Pictrues"), _L("Number of images successfully uploaded") + ": " + std::to_string(upload_nums) + "/" + std::to_string(need_upload_nums), need_upload_nums, this);
for (std::set<wxString>::iterator it = m_need_upload_images.begin(); it != m_need_upload_images.end();) { for (std::set<std::pair<wxStaticBitmap *, wxString>>::iterator it = need_upload_images.begin(); it != need_upload_images.end();) {
wxString need_upload = *it; std::pair<wxStaticBitmap *, wxString> need_upload = *it;
std::string need_upload_uf8 = into_u8(need_upload); std::string need_upload_uf8 = into_u8(need_upload.second);
ret = wxGetApp().getAgent()->put_rating_picture_oss(config, need_upload_uf8, m_model_id, m_profile_id, http_code, http_error); //Local path when incoming, cloud path when outgoing
ret = wxGetApp().getAgent()->put_rating_picture_oss(config, need_upload_uf8, m_model_id, m_profile_id, http_code, http_error);
std::unordered_map<wxStaticBitmap *, ImageMsg>::iterator iter;
switch (ret) { switch (ret) {
case 0: case 0:
upload_nums++; upload_nums++;
m_image_url_paths.push_back(need_upload_uf8); iter = m_image.find(need_upload.first);
m_local_to_url_image[*it] = need_upload_uf8; if (m_image.end() != iter) {
it = m_need_upload_images.erase(it); iter->second.img_url_paths = need_upload_uf8;
iter->second.is_uploaded = true;
m_image_url_paths.push_back(need_upload_uf8);
}
it++;
progress_dialog->Update(upload_nums, _L("Number of images successfully uploaded") + ": " + std::to_string(upload_nums) + "/" + std::to_string(need_upload_nums)); progress_dialog->Update(upload_nums, _L("Number of images successfully uploaded") + ": " + std::to_string(upload_nums) + "/" + std::to_string(need_upload_nums));
progress_dialog->Fit(); progress_dialog->Fit();
BOOST_LOG_TRIVIAL(info) << "put_rating_picture_oss: model_id [" << m_model_id << "] profile_id [" << m_profile_id << "] http_code [" << http_code BOOST_LOG_TRIVIAL(info) << "put_rating_picture_oss: model_id [" << m_model_id << "] profile_id [" << m_profile_id << "] http_code [" << http_code
<< "] http_error [" << http_error << "] config [" << config << "] image_path [" << need_upload << "]"; << "] http_error [" << http_error << "] config [" << config << "] image_path [" << need_upload.second << "]";
break; break;
case -1: case -1:
error_info += need_upload + _L(" upload failed").ToUTF8().data() + "\n\thttp code:" + std::to_string(http_code) + "\n\thttp_error:" + http_error + "\n"; error_info += need_upload.second + _L(" upload failed").ToUTF8().data() + "\n\thttp code:" + std::to_string(http_code) + "\n\thttp_error:" + http_error + "\n";
m_upload_status_code = StatusCode::UPLOAD_IMG_FAILED; m_upload_status_code = StatusCode::UPLOAD_IMG_FAILED;
++it; ++it;
break; break;
case BAMBU_NETWORK_ERR_PARSE_CONFIG_FAILED: case BAMBU_NETWORK_ERR_PARSE_CONFIG_FAILED:
error_info += need_upload + _L("upload config prase failed\n").ToUTF8().data() + "\n"; error_info += need_upload.second + _L(" upload config prase failed\n").ToUTF8().data() + "\n";
m_upload_status_code = StatusCode::UPLOAD_IMG_FAILED; m_upload_status_code = StatusCode::UPLOAD_IMG_FAILED;
++it; ++it;
break; break;
case BAMBU_NETWORK_ERR_NO_CORRESPONDING_BUCKET: case BAMBU_NETWORK_ERR_NO_CORRESPONDING_BUCKET:
error_info += need_upload + _L("No corresponding storage bucket\n").ToUTF8().data() + "\n"; error_info += need_upload.second + _L(" No corresponding storage bucket\n").ToUTF8().data() + "\n";
m_upload_status_code = StatusCode::UPLOAD_IMG_FAILED; m_upload_status_code = StatusCode::UPLOAD_IMG_FAILED;
++it; ++it;
break; break;
case BAMBU_NETWORK_ERR_OPEN_FILE_FAILED: case BAMBU_NETWORK_ERR_OPEN_FILE_FAILED:
error_info += need_upload + _L("can not be opened\n").ToUTF8().data() + "\n"; error_info += need_upload.second + _L(" can not be opened\n").ToUTF8().data() + "\n";
m_upload_status_code = StatusCode::UPLOAD_IMG_FAILED; m_upload_status_code = StatusCode::UPLOAD_IMG_FAILED;
++it; ++it;
break; break;
@ -4279,24 +4494,21 @@ wxBoxSizer *ScoreDialog::get_button_sizer()
progress_dialog->Hide(); progress_dialog->Hide();
if (progress_dialog) { if (progress_dialog) {
delete progress_dialog; delete progress_dialog;
} progress_dialog = nullptr;
for (auto bitmap : m_image) {
wxString local_image_path = bitmap.second.local_image_url;
if (m_local_to_url_image.find(local_image_path) != m_local_to_url_image.end()) {
m_image[bitmap.first].is_uploaded = true;
}
} }
if (m_upload_status_code == StatusCode::UPLOAD_IMG_FAILED) { if (m_upload_status_code == StatusCode::UPLOAD_IMG_FAILED) {
std::string upload_failed_images = into_u8(_L("The following issues occurred during the process of uploading images. Do you want to ignore them?\n\n")); std::string upload_failed_images = into_u8(_L("The following issues occurred during the process of uploading images. Do you want to ignore them?\n\n"));
MessageDialog dlg_info(this, upload_failed_images + error_info, wxString(_L("info")), wxOK | wxNO | wxCENTER); MessageDialog dlg_info(this, upload_failed_images + error_info, wxString(_L("info")), wxOK | wxNO | wxCENTER);
if (dlg_info.ShowModal() == wxID_OK) { m_upload_status_code = StatusCode::UPLOAD_PROGRESS; } if (dlg_info.ShowModal() == wxID_OK) {
m_upload_status_code = StatusCode::UPLOAD_PROGRESS;
}
} }
} }
} }
if (m_upload_status_code == StatusCode::UPLOAD_PROGRESS) { if (m_upload_status_code == StatusCode::UPLOAD_PROGRESS) {
int ret = wxGetApp().getAgent()->put_model_mall_rating(m_job_id, m_star_count, comment, m_image_url_paths, http_code, http_error); int ret = wxGetApp().getAgent()->put_model_mall_rating(m_rating_id, m_star_count, comment, m_image_url_paths, http_code, http_error);
MessageDialog *dlg_info; MessageDialog *dlg_info;
switch (ret) { switch (ret) {
case 0: EndModal(wxID_OK); break; case 0: EndModal(wxID_OK); break;
@ -4350,53 +4562,26 @@ wxBoxSizer *ScoreDialog::get_button_sizer()
return bSizer_button; return bSizer_button;
} }
void ScoreDialog::load_photo(const wxArrayString &filePaths) void ScoreDialog::load_photo(const std::vector<std::pair<wxString, std::string>> &filePaths)
{ {
for (size_t i = 0; i < filePaths.GetCount(); ++i) { for (size_t i = 0; i < filePaths.size(); ++i) {
if (m_image.size() < m_photo_nums) { if (m_image.size() < m_photo_nums) {
wxString filePath = filePaths[i]; std::pair<wxString, std::string> local_to_url_path = filePaths[i];
wxString filePath = local_to_url_path.first;
ImageMsg cur_image_msg; ImageMsg cur_image_msg;
wxStaticBitmap *imageCtrl = new wxStaticBitmap(this, wxID_ANY, wxBitmap(wxImage(filePath, wxBITMAP_TYPE_ANY).Rescale(FromDIP(80), FromDIP(60))), wxDefaultPosition,
wxDefaultSize, 0);
imageCtrl->Bind(wxEVT_LEFT_DOWN, &ScoreDialog::OnBitmapClicked, this);
cur_image_msg.local_image_url = filePath;
cur_image_msg.is_uploaded = false;
// tb: top and bottom lr: left and right if (filePath.empty()) { // local img path is empty, oss url path is exist
auto m_image_tb_broad = new wxBoxSizer(wxVERTICAL); std::string oss_url_path = local_to_url_path.second;
auto line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL); //to do: load oss image, create wxStaticBitmap
line_top->SetBackgroundColour(wxColour(0xA6, 0xa9, 0xAA));
m_image_tb_broad->Add(line_top, 0, wxEXPAND, 0);
cur_image_msg.image_broad.push_back(line_top);
line_top->Hide();
auto m_image_lr_broad = new wxBoxSizer(wxHORIZONTAL); if (!oss_url_path.empty()) {
auto line_left = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(1, -1), wxTAB_TRAVERSAL); m_image.insert(create_oss_thumbnail(oss_url_path));
line_left->SetBackgroundColour(wxColour(0xA6, 0xa9, 0xAA)); }
m_image_lr_broad->Add(line_left, 0, wxEXPAND, 0); continue;
cur_image_msg.image_broad.push_back(line_left); } else {
line_left->Hide(); m_image.insert(create_local_thumbnail(filePath));
}
m_image_lr_broad->Add(imageCtrl, 0, wxALL, 5);
auto line_right = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(1, -1), wxTAB_TRAVERSAL);
line_right->SetBackgroundColour(wxColour(0xA6, 0xa9, 0xAA));
m_image_lr_broad->Add(line_right, 0, wxEXPAND, 0);
m_image_tb_broad->Add(m_image_lr_broad, 0, wxEXPAND, 0);
cur_image_msg.image_broad.push_back(line_right);
line_right->Hide();
auto line_bottom = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
line_bottom->SetBackgroundColour(wxColour(0xA6, 0xa9, 0xAA));
m_image_tb_broad->Add(line_bottom, 0, wxEXPAND, 0);
cur_image_msg.image_broad.push_back(line_bottom);
line_bottom->Hide();
cur_image_msg.is_selected = false;
cur_image_msg.image_tb_broad = m_image_tb_broad;
m_image[imageCtrl] = cur_image_msg;
m_image_sizer->Add(m_image_tb_broad, 0, wxALL, 5);
} else { } else {
MessageDialog *dlg_info_up_to_8 = new MessageDialog(this, _L("You can select up to 5 images."), wxString(_L("info")), wxOK | wxCENTER); MessageDialog *dlg_info_up_to_8 = new MessageDialog(this, _L("You can select up to 5 images."), wxString(_L("info")), wxOK | wxCENTER);
@ -4407,7 +4592,8 @@ void ScoreDialog::load_photo(const wxArrayString &filePaths)
} }
} }
wxBoxSizer *ScoreDialog::get_main_sizer(const wxArrayString &images, const wxString &comment) { wxBoxSizer *ScoreDialog::get_main_sizer(const std::vector<std::pair<wxString, std::string>> &images, const wxString &comment)
{
init(); init();
wxBoxSizer *m_main_sizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer *m_main_sizer = new wxBoxSizer(wxVERTICAL);
// top line // top line
@ -4416,6 +4602,10 @@ wxBoxSizer *ScoreDialog::get_main_sizer(const wxArrayString &images, const wxStr
m_main_sizer->Add(m_line_top, 0, wxEXPAND, 0); m_main_sizer->Add(m_line_top, 0, wxEXPAND, 0);
m_main_sizer->Add(0, 0, 0, wxTOP, FromDIP(32)); m_main_sizer->Add(0, 0, 0, wxTOP, FromDIP(32));
warning_text = new wxStaticText(this, wxID_ANY, _L("At least one successful print record of this print profile is required \nto give a positive rating(4 or 5stars)."));
warning_text->SetForegroundColour(*wxRED);
warning_text->SetFont(::Label::Body_13);
wxBoxSizer *score_sizer = get_score_sizer(); wxBoxSizer *score_sizer = get_score_sizer();
m_main_sizer->Add(score_sizer, 0, wxEXPAND, FromDIP(20)); m_main_sizer->Add(score_sizer, 0, wxEXPAND, FromDIP(20));
m_main_sizer->Add(0, 0, 0, wxBOTTOM, FromDIP(8)); m_main_sizer->Add(0, 0, 0, wxBOTTOM, FromDIP(8));
@ -4423,6 +4613,10 @@ wxBoxSizer *ScoreDialog::get_main_sizer(const wxArrayString &images, const wxStr
wxBoxSizer *static_score_star_sizer = get_star_sizer(); wxBoxSizer *static_score_star_sizer = get_star_sizer();
m_main_sizer->Add(static_score_star_sizer, 0, wxEXPAND | wxBOTTOM, FromDIP(20)); m_main_sizer->Add(static_score_star_sizer, 0, wxEXPAND | wxBOTTOM, FromDIP(20));
m_main_sizer->Add(warning_text, 0, wxEXPAND | wxLEFT, FromDIP(24));
m_main_sizer->Add(0, 0, 0, wxBOTTOM, FromDIP(8));
warning_text->Hide();
wxBoxSizer *m_comment_sizer = get_comment_text_sizer(); wxBoxSizer *m_comment_sizer = get_comment_text_sizer();
m_main_sizer->Add(m_comment_sizer, 0, wxEXPAND, FromDIP(20)); m_main_sizer->Add(m_comment_sizer, 0, wxEXPAND, FromDIP(20));
m_main_sizer->Add(0, 0, 0, wxBOTTOM, FromDIP(8)); m_main_sizer->Add(0, 0, 0, wxBOTTOM, FromDIP(8));
@ -4433,7 +4627,7 @@ wxBoxSizer *ScoreDialog::get_main_sizer(const wxArrayString &images, const wxStr
wxBoxSizer *m_photo_sizer = get_photo_btn_sizer(); wxBoxSizer *m_photo_sizer = get_photo_btn_sizer();
m_main_sizer->Add(m_photo_sizer, 0, wxEXPAND | wxTOP, FromDIP(8)); m_main_sizer->Add(m_photo_sizer, 0, wxEXPAND | wxTOP, FromDIP(8));
m_image_sizer = new wxBoxSizer(wxHORIZONTAL); m_image_sizer = new wxGridSizer(5, FromDIP(5), FromDIP(5));
if (!images.empty()) { if (!images.empty()) {
load_photo(images); load_photo(images);
} }
@ -4448,19 +4642,37 @@ wxBoxSizer *ScoreDialog::get_main_sizer(const wxArrayString &images, const wxStr
ScoreData ScoreDialog::get_score_data() { ScoreData ScoreDialog::get_score_data() {
ScoreData score_data; ScoreData score_data;
score_data.design_id = m_design_id; score_data.rating_id = m_rating_id;
score_data.job_id = m_job_id; score_data.design_id = m_design_id;
score_data.model_id = m_model_id; score_data.model_id = m_model_id;
score_data.profile_id = m_profile_id; score_data.profile_id = m_profile_id;
score_data.star_count = m_star_count; score_data.star_count = m_star_count;
score_data.comment_text = m_comment_text->GetValue(); score_data.success_printed = m_success_printed;
score_data.image_url_paths = m_image_url_paths; score_data.comment_text = m_comment_text->GetValue();
score_data.need_upload_images = m_need_upload_images; score_data.image_url_paths = m_image_url_paths;
for (auto img : m_image) { score_data.image.push_back(img.second.local_image_url); } for (auto img : m_image) { score_data.local_to_url_image.push_back(std::make_pair(img.second.local_image_url, img.second.img_url_paths)); }
score_data.local_to_url_image = m_local_to_url_image;
return score_data; return score_data;
} }
void ScoreDialog::set_comment(std::string comment)
{
if (m_comment_text) {
m_comment_text->SetValue(wxString::FromUTF8(comment));
}
}
void ScoreDialog::set_cloud_bitmap(std::vector<std::string> cloud_bitmaps)
{
m_image_url_paths = cloud_bitmaps;
for (std::string &url : cloud_bitmaps) {
if (std::string::npos == url.find(m_model_id)) continue;
m_image.insert(create_oss_thumbnail(url));
}
Layout();
Fit();
}
} // namespace GUI } // namespace GUI
} // namespace Slic3r } // namespace Slic3r

View File

@ -62,16 +62,16 @@ enum PrintingTaskType {
struct ScoreData struct ScoreData
{ {
int rating_id;
int design_id; int design_id;
int job_id;
std::string model_id; std::string model_id;
int profile_id; int profile_id;
int star_count; int star_count;
bool success_printed;
wxString comment_text; wxString comment_text;
std::vector<std::string> image_url_paths; std::vector<std::string> image_url_paths;
std::set<wxString> need_upload_images; std::set<wxString> need_upload_images;
wxArrayString image; std::vector<std::pair<wxString, std::string>> local_to_url_image;
std::unordered_map<wxString, std::string> local_to_url_image;
}; };
typedef std::function<void(BBLModelTask* subtask)> OnGetSubTaskFn; typedef std::function<void(BBLModelTask* subtask)> OnGetSubTaskFn;
@ -79,12 +79,14 @@ typedef std::function<void(BBLModelTask* subtask)> OnGetSubTaskFn;
class ScoreDialog : public GUI::DPIDialog class ScoreDialog : public GUI::DPIDialog
{ {
public: public:
ScoreDialog(wxWindow *parent, int design_id, int job_id, std::string model_id, int profile_id, int star_count = 0); ScoreDialog(wxWindow *parent, int design_id, std::string model_id, int profile_id, int rating_id, bool success_printed, int star_count = 0);
ScoreDialog(wxWindow *parent, ScoreData *score_data); ScoreDialog(wxWindow *parent, ScoreData *score_data);
~ScoreDialog(); ~ScoreDialog();
int get_job_id() { return m_job_id;} int get_rating_id() { return m_rating_id; }
ScoreData get_score_data(); ScoreData get_score_data();
void set_comment(std::string comment);
void set_cloud_bitmap(std::vector<std::string> cloud_bitmaps);
protected: protected:
enum StatusCode { enum StatusCode {
@ -94,23 +96,24 @@ protected:
CODE_NUMBER CODE_NUMBER
}; };
const int m_photo_nums = 5; std::shared_ptr<int> m_tocken;
const int m_photo_nums = 16;
int m_rating_id;
int m_design_id; int m_design_id;
int m_job_id;
std::string m_model_id; std::string m_model_id;
int m_profile_id; int m_profile_id;
int m_star_count; int m_star_count;
bool m_success_printed;
std::vector<std::string> m_image_url_paths; std::vector<std::string> m_image_url_paths;
std::set<wxString> m_need_upload_images;
std::string m_upload_error_info;
StatusCode m_upload_status_code; StatusCode m_upload_status_code;
struct ImageMsg struct ImageMsg
{ {
wxString local_image_url; wxString local_image_url; //local image path
vector<wxPanel *> image_broad; std::string img_url_paths; // oss url path
vector<wxPanel *> image_broad;
bool is_selected; bool is_selected;
bool is_uploaded; bool is_uploaded; // load
wxBoxSizer * image_tb_broad = nullptr; wxBoxSizer * image_tb_broad = nullptr;
}; };
@ -120,24 +123,30 @@ protected:
Button * m_button_cancel = nullptr; Button * m_button_cancel = nullptr;
Label * m_add_photo = nullptr; Label * m_add_photo = nullptr;
Label * m_delete_photo = nullptr; Label * m_delete_photo = nullptr;
wxBoxSizer * m_image_sizer = nullptr; wxGridSizer * m_image_sizer = nullptr;
wxStaticText * warning_text = nullptr;
std::unordered_map<wxStaticBitmap *, ImageMsg> m_image; std::unordered_map<wxStaticBitmap *, ImageMsg> m_image;
std::unordered_set<wxStaticBitmap *> m_selected_image_list; std::unordered_set<wxStaticBitmap *> m_selected_image_list;
std::unordered_map<wxString, std::string> m_local_to_url_image;
void on_dpi_changed(const wxRect &suggested_rect) override;
void OnBitmapClicked(wxMouseEvent &event);
void add_need_upload_imgs();
void init(); void init();
wxBoxSizer *get_score_sizer(); void update_static_bitmap(wxStaticBitmap *static_bitmap, wxImage image);
wxBoxSizer *get_star_sizer(); void create_comment_text(const wxString &comment = "");
wxBoxSizer *get_comment_text_sizer(); void load_photo(const std::vector<std::pair<wxString, std::string>> &filePaths);
void create_comment_text(const wxString& comment = ""); void on_dpi_changed(const wxRect &suggested_rect) override;
wxBoxSizer *get_photo_btn_sizer(); void OnBitmapClicked(wxMouseEvent &event);
wxBoxSizer *get_button_sizer();
void load_photo(const wxArrayString &filePaths); wxBoxSizer * create_broad_sizer(wxStaticBitmap *bitmap, ImageMsg &cur_image_msg);
wxBoxSizer *get_main_sizer(const wxArrayString &images = wxArrayString(), const wxString &comment = ""); wxBoxSizer * get_score_sizer();
wxBoxSizer * get_star_sizer();
wxBoxSizer * get_comment_text_sizer();
wxBoxSizer * get_photo_btn_sizer();
wxBoxSizer * get_button_sizer();
wxBoxSizer * get_main_sizer(const std::vector<std::pair<wxString, std::string>> &images = std::vector<std::pair<wxString, std::string>>(), const wxString &comment = "");
std::set<std::pair<wxStaticBitmap *, wxString>> add_need_upload_imgs();
std::pair<wxStaticBitmap *, ImageMsg> create_local_thumbnail(wxString &local_path);
std::pair<wxStaticBitmap *, ImageMsg> create_oss_thumbnail(std::string &oss_path);
}; };
class PrintingTaskPanel : public wxPanel class PrintingTaskPanel : public wxPanel
@ -146,6 +155,7 @@ public:
PrintingTaskPanel(wxWindow* parent, PrintingTaskType type); PrintingTaskPanel(wxWindow* parent, PrintingTaskType type);
~PrintingTaskPanel(); ~PrintingTaskPanel();
void create_panel(wxWindow* parent); void create_panel(wxWindow* parent);
private: private:
MachineObject* m_obj; MachineObject* m_obj;
@ -177,8 +187,10 @@ private:
Button* m_button_clean; Button* m_button_clean;
wxPanel * m_score_subtask_info; wxPanel * m_score_subtask_info;
wxPanel * m_score_staticline; wxPanel * m_score_staticline;
// score page
int m_star_count; int m_star_count;
std::vector<ScalableButton *> m_score_star; std::vector<ScalableButton *> m_score_star;
bool m_star_count_dirty = false;
ProgressBar* m_gauge_progress; ProgressBar* m_gauge_progress;
Label* m_error_text; Label* m_error_text;
@ -213,6 +225,11 @@ public:
Button* get_clean_button() {return m_button_clean;}; Button* get_clean_button() {return m_button_clean;};
wxStaticBitmap* get_bitmap_thumbnail() {return m_bitmap_thumbnail;}; wxStaticBitmap* get_bitmap_thumbnail() {return m_bitmap_thumbnail;};
int get_star_count() { return m_star_count; } int get_star_count() { return m_star_count; }
void set_star_count(int star_count);
std::vector<ScalableButton *> &get_score_star() { return m_score_star; }
bool get_star_count_dirty() { return m_star_count_dirty; }
void set_star_count_dirty(bool dirty) { m_star_count_dirty = dirty; }
}; };
class StatusBasePanel : public wxScrolledWindow class StatusBasePanel : public wxScrolledWindow
@ -294,7 +311,6 @@ protected:
ScalableButton *m_button_pause_resume; ScalableButton *m_button_pause_resume;
ScalableButton *m_button_abort; ScalableButton *m_button_abort;
Button * m_button_clean; Button * m_button_clean;
Button * m_button_market_scoring;
wxStaticText * m_text_tasklist_caption; wxStaticText * m_text_tasklist_caption;
@ -446,6 +462,8 @@ protected:
int m_last_vcamera = -1; int m_last_vcamera = -1;
bool m_is_load_with_temp = false; bool m_is_load_with_temp = false;
bool m_print_finish = false; bool m_print_finish = false;
json m_rating_result;
json m_last_result;
wxWebRequest web_request; wxWebRequest web_request;
bool bed_temp_input = false; bool bed_temp_input = false;
@ -556,6 +574,9 @@ protected:
void on_webrequest_state(wxWebRequestEvent &evt); void on_webrequest_state(wxWebRequestEvent &evt);
bool is_task_changed(MachineObject* obj); bool is_task_changed(MachineObject* obj);
/* model mall score */
bool model_score_is_update();
/* camera */ /* camera */
void update_camera_state(MachineObject* obj); void update_camera_state(MachineObject* obj);
bool show_vcamera = false; bool show_vcamera = false;

View File

@ -111,6 +111,7 @@ func_track_get_property NetworkAgent::track_get_property_ptr = nullp
func_put_model_mall_rating_url NetworkAgent::put_model_mall_rating_url_ptr = nullptr; func_put_model_mall_rating_url NetworkAgent::put_model_mall_rating_url_ptr = nullptr;
func_get_oss_config NetworkAgent::get_oss_config_ptr = nullptr; func_get_oss_config NetworkAgent::get_oss_config_ptr = nullptr;
func_put_rating_picture_oss NetworkAgent::put_rating_picture_oss_ptr = nullptr; func_put_rating_picture_oss NetworkAgent::put_rating_picture_oss_ptr = nullptr;
func_get_model_mall_rating_result NetworkAgent::get_model_mall_rating_result_ptr = nullptr;
NetworkAgent::NetworkAgent() NetworkAgent::NetworkAgent()
@ -268,6 +269,7 @@ int NetworkAgent::initialize_network_module(bool using_backup)
put_model_mall_rating_url_ptr = reinterpret_cast<func_put_model_mall_rating_url>(get_network_function("bambu_network_put_model_mall_rating")); put_model_mall_rating_url_ptr = reinterpret_cast<func_put_model_mall_rating_url>(get_network_function("bambu_network_put_model_mall_rating"));
get_oss_config_ptr = reinterpret_cast<func_get_oss_config>(get_network_function("bambu_network_get_oss_config")); get_oss_config_ptr = reinterpret_cast<func_get_oss_config>(get_network_function("bambu_network_get_oss_config"));
put_rating_picture_oss_ptr = reinterpret_cast<func_put_rating_picture_oss>(get_network_function("bambu_network_put_rating_picture_oss")); put_rating_picture_oss_ptr = reinterpret_cast<func_put_rating_picture_oss>(get_network_function("bambu_network_put_rating_picture_oss"));
get_model_mall_rating_result_ptr = reinterpret_cast<func_get_model_mall_rating_result>(get_network_function("bambu_network_get_model_mall_rating"));
return 0; return 0;
} }
@ -378,6 +380,7 @@ int NetworkAgent::unload_network_module()
get_oss_config_ptr = nullptr; get_oss_config_ptr = nullptr;
put_rating_picture_oss_ptr = nullptr; put_rating_picture_oss_ptr = nullptr;
put_model_mall_rating_url_ptr = nullptr; put_model_mall_rating_url_ptr = nullptr;
get_model_mall_rating_result_ptr = nullptr;
return 0; return 0;
} }
@ -1306,12 +1309,11 @@ int NetworkAgent::track_get_property(std::string name, std::string& value, std::
return ret; return ret;
} }
int NetworkAgent::put_model_mall_rating( int NetworkAgent::put_model_mall_rating(int rating_id, int score, std::string content, std::vector<std::string> images, unsigned int &http_code, std::string &http_error)
int design_id, int score, std::string content, std::vector<std::string> images, unsigned int &http_code, std::string &http_error)
{ {
int ret = 0; int ret = 0;
if (network_agent && get_model_publish_url_ptr) { if (network_agent && get_model_publish_url_ptr) {
ret = put_model_mall_rating_url_ptr(network_agent, design_id, score, content, images, http_code, http_error); ret = put_model_mall_rating_url_ptr(network_agent, rating_id, score, content, images, http_code, http_error);
if (ret) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(" error: network_agent=%1%, ret=%2%") % network_agent % ret; if (ret) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(" error: network_agent=%1%, ret=%2%") % network_agent % ret;
} }
return ret; return ret;
@ -1337,4 +1339,14 @@ int NetworkAgent::put_rating_picture_oss(std::string &config, std::string &pic_o
return ret; return ret;
} }
int NetworkAgent::get_model_mall_rating_result(int job_id, std::string &rating_result, unsigned int &http_code, std::string &http_error)
{
int ret = 0;
if (network_agent && get_model_mall_rating_result_ptr) {
ret = get_model_mall_rating_result_ptr(network_agent, job_id, rating_result, http_code, http_error);
if (ret) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(" error: network_agent=%1%, ret=%2%") % network_agent % ret;
}
return ret;
}
} //namespace } //namespace

View File

@ -89,10 +89,11 @@ typedef int (*func_track_header)(void *agent, std::string header);
typedef int (*func_track_update_property)(void *agent, std::string name, std::string value, std::string type); typedef int (*func_track_update_property)(void *agent, std::string name, std::string value, std::string type);
typedef int (*func_track_get_property)(void *agent, std::string name, std::string& value, std::string type); typedef int (*func_track_get_property)(void *agent, std::string name, std::string& value, std::string type);
typedef int (*func_put_model_mall_rating_url)( typedef int (*func_put_model_mall_rating_url)(
void *agent, int design_id, int score, std::string content, std::vector<std::string> images, unsigned int &http_code, std::string &http_error); void *agent, int rating_id, int score, std::string content, std::vector<std::string> images, unsigned int &http_code, std::string &http_error);
typedef int (*func_get_oss_config)(void *agent, std::string &config, std::string country_code, unsigned int &http_code, std::string &http_error); typedef int (*func_get_oss_config)(void *agent, std::string &config, std::string country_code, unsigned int &http_code, std::string &http_error);
typedef int (*func_put_rating_picture_oss)( typedef int (*func_put_rating_picture_oss)(
void *agent, std::string &config, std::string &pic_oss_path, std::string model_id, int profile_id, unsigned int &http_code, std::string &http_error); void *agent, std::string &config, std::string &pic_oss_path, std::string model_id, int profile_id, unsigned int &http_code, std::string &http_error);
typedef int (*func_get_model_mall_rating_result)(void *agent, int job_id, std::string &rating_result, unsigned int &http_code, std::string &http_error);
//the NetworkAgent class //the NetworkAgent class
@ -191,7 +192,8 @@ public:
int track_get_property(std::string name, std::string& value, std::string type = "string"); int track_get_property(std::string name, std::string& value, std::string type = "string");
int put_model_mall_rating(int design_id, int score, std::string content, std::vector<std::string> images, unsigned int &http_code, std::string &http_error); int put_model_mall_rating(int design_id, int score, std::string content, std::vector<std::string> images, unsigned int &http_code, std::string &http_error);
int get_oss_config(std::string &config, std::string country_code, unsigned int &http_code, std::string &http_error); int get_oss_config(std::string &config, std::string country_code, unsigned int &http_code, std::string &http_error);
int put_rating_picture_oss(std::string &config, std::string &pic_oss_path, std::string model_id, int profile_id, unsigned int &http_code, std::string &http_error); int put_rating_picture_oss(std::string &config, std::string &pic_oss_path, std::string model_id, int profile_id, unsigned int &http_code, std::string &http_error);
int get_model_mall_rating_result(int job_id, std::string &rating_result, unsigned int &http_code, std::string &http_error);
bool get_track_enable() { return enable_track; } bool get_track_enable() { return enable_track; }
private: private:
bool enable_track = false; bool enable_track = false;
@ -281,6 +283,7 @@ private:
static func_put_model_mall_rating_url put_model_mall_rating_url_ptr; static func_put_model_mall_rating_url put_model_mall_rating_url_ptr;
static func_get_oss_config get_oss_config_ptr; static func_get_oss_config get_oss_config_ptr;
static func_put_rating_picture_oss put_rating_picture_oss_ptr; static func_put_rating_picture_oss put_rating_picture_oss_ptr;
static func_get_model_mall_rating_result get_model_mall_rating_result_ptr;
}; };
} }