Update device

This commit is contained in:
QIDI TECH
2024-07-26 14:02:02 +08:00
parent 2b8deba938
commit 5005a1df1b
79 changed files with 29198 additions and 1058 deletions

View File

@@ -1884,7 +1884,8 @@ void GUI_App::check_printer_presets()
void GUI_App::recreate_GUI(const wxString& msg_name)
{
m_is_recreating_gui = true;
// y1
mainframe->m_printer_view->StopStatusThread();
mainframe->shutdown();
wxProgressDialog dlg(msg_name, msg_name, 100, nullptr, wxPD_AUTO_HIDE);
@@ -1934,6 +1935,35 @@ void GUI_App::keyboard_shortcuts()
dlg.ShowModal();
}
//B64
void GUI_App::ShowUserLogin(bool show)
{
// QDS: User Login Dialog
if (show) {
try {
if (!login_dlg)
login_dlg = new ZUserLogin();
else {
delete login_dlg;
login_dlg = new ZUserLogin();
}
login_dlg->ShowModal();
} catch (std::exception &e) {
;
}
} else {
if (login_dlg)
login_dlg->EndModal(wxID_OK);
}
}
void GUI_App::SetOnlineLogin(bool status)
{
mainframe->m_printer_view->SetLoginStatus(status);
}
void GUI_App::SetPresentChange(bool status)
{ mainframe->m_printer_view->SetPresetChanged(status); }
// static method accepting a wxWindow object as first parameter
bool GUI_App::catch_error(std::function<void()> cb,
// wxMessageDialog* message_dialog,

View File

@@ -17,6 +17,9 @@
#include <mutex>
#include <stack>
//B64
#include "../Utils/QIDINetwork.hpp"
#include "slic3r/GUI/WebUserLoginDialog.hpp"
class wxMenuItem;
class wxMenuBar;
class wxTopLevelWindow;
@@ -142,6 +145,13 @@ private:
wxColour m_color_selected_btn_bg;
bool m_force_colors_update { false };
#endif
//B64
#if QDT_RELEASE_TO_PUBLIC
std::vector<Device> m_devices;
#endif
//B64
ZUserLogin *login_dlg{nullptr};
std::vector<std::string> m_mode_palette;
wxFont m_small_font;
@@ -244,6 +254,11 @@ public:
#ifdef _MSW_DARK_MODE
void force_menu_update();
#endif //_MSW_DARK_MODE
#endif
//B64
#if QDT_RELEASE_TO_PUBLIC
std::vector<Device> get_devices() { return m_devices; };
void set_devices(std::vector<Device> devices) { m_devices = devices; };
#endif
const wxFont& small_font() { return m_small_font; }
@@ -263,6 +278,10 @@ public:
void recreate_GUI(const wxString& message);
void system_info();
void keyboard_shortcuts();
//B64
void ShowUserLogin(bool show);
void SetOnlineLogin(bool status);
void SetPresentChange(bool status);
void load_project(wxWindow *parent, wxString& input_file) const;
void import_model(wxWindow *parent, wxArrayString& input_files) const;
void import_zip(wxWindow* parent, wxString& input_file) const;

View File

@@ -62,6 +62,8 @@
//B55
#include "../Utils/PrintHost.hpp"
//B64
#include "../Utils/QIDINetwork.hpp"
namespace Slic3r {
namespace GUI {
wxDEFINE_EVENT(EVT_LOAD_URL, wxCommandEvent);
@@ -252,8 +254,9 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
event.Veto();
return;
}
//B64
m_printer_view->StopStatusThread();
this->shutdown();
m_printer_view->StopAllThread();
// propagate event
event.Skip();
});
@@ -753,9 +756,7 @@ void MainFrame::init_tabpanel()
m_tabpanel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, [this](wxBookCtrlEvent& e) {
#endif
//B45
// #if defined(__WIN32__) || defined(__WXMAC__)
// m_printer_view->PauseButton();
// #endif
m_printer_view->SetPauseThread(true);
if (int old_selection = e.GetOldSelection();
old_selection != wxNOT_FOUND && old_selection < static_cast<int>(m_tabpanel->GetPageCount())) {
Tab* old_tab = dynamic_cast<Tab*>(m_tabpanel->GetPage(old_selection));
@@ -2056,132 +2057,46 @@ void MainFrame::select_tab(size_t tab/* = size_t(-1)*/)
auto select = [this, tab](bool was_hidden) {
// when tab == -1, it means we should show the last selected tab
size_t new_selection = tab == (size_t)(-1) ? m_last_selected_tab : (m_layout == ESettingsLayout::Dlg && tab != 0) ? tab - 1 : tab;
//B4
//B4 //B64
if (m_tabpanel->GetSelection() == 4) {
//B45 //B59 //B60
PresetBundle &preset_bundle = *wxGetApp().preset_bundle;
const PhysicalPrinterCollection &ph_printers = preset_bundle.physical_printers;
struct PhysicalPrinterPresetData
{
wxString printer_name; // just for sorting
wxString name; // preset_name
wxString fullname; // full name
bool selected; // is selected
std::string model_id;
wxString host;
bool is_QIDI;
std::string preset_name;
};
std::vector<PhysicalPrinterPresetData> preset_data;
PhysicalPrinterCollection &ph_printers = preset_bundle.physical_printers;
std::vector<std::string> vec1;
std::vector<std::string> vec2;
for (PhysicalPrinterCollection::ConstIterator it = ph_printers.begin(); it != ph_printers.end(); ++it) {
for (const std::string &preset_name : it->get_preset_names()) {
Preset *preset = wxGetApp().preset_bundle->printers.find_preset(preset_name);
if (preset != nullptr) {
std::string model_id;
if (preset != nullptr) {
if ((preset->config.opt_string("printer_model").empty()))
model_id = "my_printer";
else
model_id = preset->config.opt_string("printer_model");
}
//B59 //B60
wxStringTokenizer tokenizer(wxString::FromUTF8(it->get_full_name(preset_name)), "*");
std::string tem_name = (into_u8(tokenizer.GetNextToken().Trim().mb_str()));
auto * printer = preset_bundle.physical_printers.find_printer(tem_name);
wxString printer_name = "";
wxString host = "";
bool is_QIDI = false;
auto host_type = htOctoPrint;
if (printer != nullptr) {
host = (printer->config.opt_string("print_host"));
bool isValidIPAddress = true;
DynamicPrintConfig *cfg_t = &(printer->config);
const auto opt = cfg_t->option<ConfigOptionEnum<PrintHostType>>("host_type");
host_type = opt != nullptr ? opt->value : htOctoPrint;
//B67
wxStringTokenizer tokenizer3((wxString::FromUTF8(it->get_full_name(preset_name))), wxT("*"),
wxTOKEN_RET_EMPTY_ALL);
printer_name = tokenizer3.GetNextToken();
}
preset_data.push_back({printer_name, wxString::FromUTF8(preset_name),
wxString::FromUTF8(it->get_full_name(preset_name)), ph_printers.is_selected(it, preset_name),
model_id, host, (host_type == htMoonraker), preset_name});
}
}
}
m_collection = &preset_bundle.printers;
std::vector<const PhysicalPrinterPresetData *> missingPresets;
std::vector<MachineListButton *> m_buttons = (m_printer_view->GetButton());
for (auto it = m_buttons.begin(); it != m_buttons.end();) {
bool foundPreset = false;
for (const PhysicalPrinterPresetData &data : preset_data) {
//B59
if ((*it)->getLabel() == data.fullname && (*it)->getIPLabel() == data.host && (*it)->getIsQIDI() == data.is_QIDI) {
foundPreset = true;
break;
}
}
if (!foundPreset) {
(*it)->StopStatusThread();
delete *it;
it = m_buttons.erase(it);
m_printer_view->SetButtons(m_buttons);
m_printer_view->UpdateLayout();
} else {
++it;
std::string full_name = it->get_full_name(preset_name);
vec1.push_back(full_name);
}
}
for (const PhysicalPrinterPresetData &data : preset_data) {
bool foundButton = false;
for (MachineListButton *button : m_buttons) {
if (button->getLabel() == data.fullname) {
foundButton = true;
break;
}
}
if (!foundButton) {
missingPresets.push_back(&data);
}
for (DeviceButton *button : m_printer_view->GetButton()) {
vec2.push_back(button->GetLabel().ToStdString());
}
//B59 //B60
for (const PhysicalPrinterPresetData *data : missingPresets) {
Preset *preset = m_collection->find_preset((data->preset_name));
if (!preset || !preset->is_visible)
continue;
wxStringTokenizer tokenizer((data->fullname), "*");
std::string tem_name = (into_u8(tokenizer.GetNextToken().Trim().mb_str()));
auto * printer = preset_bundle.physical_printers.find_printer(tem_name);
if (printer != nullptr) {
// wxString host = (printer->config.opt_string("print_host"));
// bool isValidIPAddress = true;
DynamicPrintConfig *cfg_t = &(printer->config);
// const auto opt = cfg_t->option<ConfigOptionEnum<PrintHostType>>("host_type");
// const auto host_type = opt != nullptr ? opt->value : htOctoPrint;
// wxStringTokenizer tokenizer3((data->lower_name), wxT("*"), wxTOKEN_RET_EMPTY_ALL);
// wxString printer_name = tokenizer3.GetNextToken();
//if (isValidIPAddress) {
m_printer_view->AddButton(
(data->printer_name), (data->host), (data->model_id), (data->fullname), (data->selected),
(data->is_QIDI), cfg_t);
bool result1 = std::equal(vec1.begin(), vec1.end(), vec2.begin(), vec2.end());
vec1.clear();
vec2.clear();
//#if QDT_RELEASE_TO_PUBLIC
// wxString msg;
// QIDINetwork m_qidinetwork;
// m_qidinetwork.get_device_list(msg);
// auto m_devices = wxGetApp().get_devices();
// for (const auto &device : m_devices) {
// vec1.push_back(device.device_name);
// }
// for (DeviceButton *button : m_printer_view->GetNetButton()) {
// vec2.push_back(button->GetLabel().ToStdString());
//}
}
}
// bool result2 = std::equal(vec1.begin(), vec1.end(), vec2.begin(), vec2.end());
//#endif
bool result2 = true;
// m_printer_view->SetPresetChanged(!result1 || !result2);
#if defined(__WIN32__) || defined(__WXMAC__)
// m_printer_view->ResumeButton();
//B63
m_printer_view->SetFocus();
#endif
//B64
m_printer_view->SetPauseThread(false);
if (const DynamicPrintConfig *cfg = wxGetApp().preset_bundle->physical_printers.get_selected_printer_config(); cfg) {
@@ -2189,8 +2104,6 @@ void MainFrame::select_tab(size_t tab/* = size_t(-1)*/)
wxString host = pp.config.opt_string("print_host");
//B55
//B45
//std::regex ipRegex(R"(\b(?:\d{1,3}\.){3}\d{1,3}\b)");
//bool isValidIPAddress = std::regex_match(host.ToStdString(), ipRegex);
if (host.empty()) {
tem_host = "";
host = wxString::Format("file://%s/web/qidi/missing_connection.html", from_u8(resources_dir()));

View File

@@ -1408,6 +1408,16 @@ void NotificationManager::PrintHostUploadNotification::set_percentage(float perc
}
}
//B64
void NotificationManager::PrintHostUploadNotification::set_waittime(int waittime)
{
if (m_uj_state != UploadJobState::PB_CANCELLED) {
m_waittime = waittime;
m_uj_state = UploadJobState::PB_WAIT;
m_has_cancel_button = true;
init();
}
}
void NotificationManager::PrintHostUploadNotification::complete()
{
m_uj_state = UploadJobState::PB_COMPLETED;
@@ -1492,6 +1502,33 @@ void NotificationManager::PrintHostUploadNotification::render_bar(ImGuiWrapper&
ImGui::SetCursorPosX(m_left_indentation);
ImGui::SetCursorPosY(win_size_y / 2 + win_size_y / 6 - (m_multiline ? m_line_height / 4 : m_line_height / 2));
break;
//B64
case Slic3r::GUI::NotificationManager::PrintHostUploadNotification::UploadJobState::PB_WAIT: {
int hours = m_waittime / 3600;
int minutes = (m_waittime % 3600) / 60;
int seconds = m_waittime % 60;
std::string result = std::to_string(hours) + ":";
if (minutes < 10) {
result += "0";
}
result += std::to_string(minutes) + ":";
if (seconds < 10) {
result += "0";
}
result += std::to_string(seconds);
std::stringstream stream;
stream << std::fixed << std::setprecision(2) << "Still have to wait: " << result;
text = stream.str();
// text = _u8L("WAIT");
ImGui::SetCursorPosX(m_left_indentation);
ImGui::SetCursorPosY(win_size_y / 2 + win_size_y / 6 - (m_multiline ? m_line_height / 4 : m_line_height / 2));
break;
}
case Slic3r::GUI::NotificationManager::PrintHostUploadNotification::UploadJobState::PB_COMPLETED:
case Slic3r::GUI::NotificationManager::PrintHostUploadNotification::UploadJobState::PB_COMPLETED_WITH_WARNING:
// whole text with both "COMPLETED" and status message is generated in generate_text()
@@ -2321,6 +2358,22 @@ void NotificationManager::set_upload_job_notification_percentage(int id, const s
}
}
}
//B64
void NotificationManager::set_upload_job_notification_waittime(int id, const std::string &filename, const std::string &host, int waittime)
{
for (std::unique_ptr<PopNotification> &notification : m_pop_notifications) {
if (notification->get_type() == NotificationType::PrintHostUpload) {
PrintHostUploadNotification *phun = dynamic_cast<PrintHostUploadNotification *>(notification.get());
if (phun->compare_job_id(id)) {
phun->set_waittime(waittime);
if (phun->get_host() != host)
phun->set_host(host);
wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(0);
break;
}
}
}
}
void NotificationManager::set_upload_job_notification_host(int id, const std::string& host)
{
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {

View File

@@ -217,6 +217,8 @@ public:
// print host upload
void push_upload_job_notification(int id, float filesize, const std::string& filename, const std::string& host, float percentage = 0);
void set_upload_job_notification_percentage(int id, const std::string& filename, const std::string& host, float percentage);
//B64
void set_upload_job_notification_waittime(int id, const std::string &filename, const std::string &host, int waittime);
void set_upload_job_notification_host(int id, const std::string& host);
void set_upload_job_notification_status(int id, const std::string& status);
void set_upload_job_notification_comp_on_100(int id, bool comp);
@@ -487,6 +489,8 @@ private:
void render_minimize_button(ImGuiWrapper& imgui,
const float win_pos_x, const float win_pos_y) override {}
float m_percentage {0.0f};
//B64
int m_waittime{0};
bool m_has_cancel_button {false};
bool m_render_percentage {false};
@@ -583,6 +587,7 @@ private:
class PrintHostUploadNotification : public ProgressBarNotification
{
public:
//B64
enum class UploadJobState
{
PB_PROGRESS,
@@ -590,7 +595,8 @@ private:
PB_CANCELLED,
PB_COMPLETED,
PB_COMPLETED_WITH_WARNING,
PB_RESOLVING
PB_RESOLVING,
PB_WAIT
};
PrintHostUploadNotification(const NotificationData& n, NotificationIDProvider& id_provider, wxEvtHandler* evt_handler, float percentage, int job_id, float filesize, const std::string& filename, const std::string& host)
:ProgressBarNotification(n, id_provider, evt_handler)
@@ -615,6 +621,8 @@ private:
void set_complete_on_100(bool val) { m_complete_on_100 = val; }
void complete();
void complete_with_warning();
//B64
void set_waittime(int waittime);
protected:
void init() override;
void count_spaces() override;

View File

@@ -820,6 +820,8 @@ void PhysicalPrinterDialog::OnOK(wxEvent& event)
else
wxGetApp().get_tab(Preset::TYPE_PRINTER)->update_preset_choice();
//B64
wxGetApp().SetPresentChange(true);
event.Skip();
}

View File

@@ -134,6 +134,8 @@ using Slic3r::PrintHostJob;
using Slic3r::GUI::format_wxstr;
static const std::pair<unsigned int, unsigned int> THUMBNAIL_SIZE_3MF = { 256, 256 };
//B64
static const std::pair<unsigned int, unsigned int> THUMBNAIL_SIZE_SEND = {128, 160};
namespace Slic3r {
namespace GUI {
@@ -7811,6 +7813,14 @@ ThumbnailData Plater::get_thumbnailldate() {
p->generate_thumbnail(thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, thumbnail_params, Camera::EType::Ortho);
return thumbnail_data;
}
//B64
ThumbnailData Plater::get_thumbnailldate_send()
{
ThumbnailData thumbnail_data;
ThumbnailsParams thumbnail_params = {{}, false, true, true, true};
p->generate_thumbnail(thumbnail_data, THUMBNAIL_SIZE_SEND.first, THUMBNAIL_SIZE_SEND.second, thumbnail_params, Camera::EType::Ortho);
return thumbnail_data;
}
bool Plater::export_3mf(const boost::filesystem::path& output_path)
{
if (p->model.objects.empty()) {
@@ -8066,34 +8076,75 @@ void Plater::send_gcode()
wxGetApp().preset_bundle->printers.get_edited_preset().config.opt_string("printer_notes"));
}
//B53 //B62
//B53 //B62 //B64
auto pppd = dlg.pppd();
auto checkbox_states = dlg.checkbox_states();
auto checkbox_status = dlg.checkbox_states();
auto checkbox_net_status = dlg.checkbox_net_states();
int count = 0;
std::chrono::system_clock::time_point curr_time = std::chrono::system_clock::now();
auto diff = std::chrono::duration_cast<std::chrono::seconds>(curr_time - m_time_p);
for (int i = 0; i < pppd.size(); i++) {
if (checkbox_states[i]) {
PresetBundle &preset_bundle = *wxGetApp().preset_bundle;
auto m_collection = &preset_bundle.printers;
if (checkbox_status[i]) {
auto preset_data = pppd[i];
PrintHostJob upload_job(preset_data.cfg_t);
Preset *preset = m_collection->find_preset(preset_data.preset_name);
if (!preset || !preset->is_visible)
continue;
wxStringTokenizer tokenizer((preset_data.fullname), "*");
std::string tem_name = (into_u8(tokenizer.GetNextToken().Trim().mb_str()));
auto * printer = preset_bundle.physical_printers.find_printer(tem_name);
if (printer == nullptr)
if (upload_job.empty())
return;
DynamicPrintConfig *cfg_t = &(printer->config);
PrintHostJob upload_job(cfg_t);
upload_job.upload_data.upload_path = dlg.filename();
upload_job.upload_data.post_action = dlg.post_action();
upload_job.upload_data.group = dlg.group();
upload_job.upload_data.storage = dlg.storage();
upload_job.create_time = std::chrono::system_clock::now();
if (diff.count()<0)
upload_job.sendinginterval = count / std::stoi(wxGetApp().app_config->get("max_send")) *
std::stoi(wxGetApp().app_config->get("sending_interval")) * 60 -
diff.count()+4;
else
upload_job.sendinginterval = count / std::stoi(wxGetApp().app_config->get("max_send")) *
std::stoi(wxGetApp().app_config->get("sending_interval")) * 60;
// Show "Is printer clean" dialog for QIDIConnect - Upload and print.
if (std::string(upload_job.printhost->get_name()) == "QIDIConnect" &&
upload_job.upload_data.post_action == PrintHostPostUploadAction::StartPrint) {
GUI::MessageDialog dlg(nullptr, _L("Is the printer ready? Is the print sheet in place, empty and clean?"),
_L("Upload and Print"), wxOK | wxCANCEL);
if (dlg.ShowModal() != wxID_OK)
return;
}
std::chrono::seconds seconds_to_add(upload_job.sendinginterval);
m_time_p = upload_job.create_time + seconds_to_add;
p->export_gcode(fs::path(), false, std::move(upload_job));
count++;
}
}
#if QDT_RELEASE_TO_PUBLIC
auto m_devices = wxGetApp().get_devices();
for (int i = 0; i < m_devices.size(); i++) {
if (checkbox_net_status[i]) {
auto device = m_devices[i];
PrintHostJob upload_job(device.url,device.local_ip);
if (upload_job.empty())
return;
upload_job.upload_data.upload_path = dlg.filename();
upload_job.upload_data.post_action = dlg.post_action();
upload_job.upload_data.group = dlg.group();
upload_job.upload_data.storage = dlg.storage();
upload_job.create_time = std::chrono::system_clock::now();
if (diff.count() < 0)
upload_job.sendinginterval = count / std::stoi(wxGetApp().app_config->get("max_send")) *
std::stoi(wxGetApp().app_config->get("sending_interval")) * 60 -
diff.count()+4;
else
upload_job.sendinginterval = count / std::stoi(wxGetApp().app_config->get("max_send")) *
std::stoi(wxGetApp().app_config->get("sending_interval")) * 60;
// Show "Is printer clean" dialog for QIDIConnect - Upload and print.
if (std::string(upload_job.printhost->get_name()) == "QIDIConnect" &&
@@ -8104,9 +8155,14 @@ void Plater::send_gcode()
return;
}
std::chrono::seconds seconds_to_add(upload_job.sendinginterval);
m_time_p = upload_job.create_time + seconds_to_add;
p->export_gcode(fs::path(), false, std::move(upload_job));
count++;
}
}
#endif
}
}

View File

@@ -295,6 +295,8 @@ public:
//B61
ThumbnailData get_thumbnailldate();
//B64
ThumbnailData get_thumbnailldate_send();
void export_gcode(bool prefer_removable);
void export_stl_obj(bool extended = false, bool selection_only = false);
void export_amf();
@@ -542,6 +544,9 @@ private:
void allow_snapshots();
friend class SuppressBackgroundProcessingUpdate;
//B64
std::thread m_sendThread;
std::chrono::system_clock::time_point m_time_p;
};
class SuppressBackgroundProcessingUpdate

View File

@@ -70,8 +70,8 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path & path,
auto *label_dir_hint2 = new wxStaticText(this, wxID_ANY, _L("Upload to Printer Host with the following filename:"));
label_dir_hint2->Wrap(CONTENT_WIDTH * wxGetApp().em_unit());
//B61
ThumbnailData thumbnail_data = m_plater->get_thumbnailldate();
//B61 //B64
ThumbnailData thumbnail_data = m_plater->get_thumbnailldate_send();
wxImage image(thumbnail_data.width, thumbnail_data.height);
image.InitAlpha();
@@ -88,10 +88,19 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path & path,
wxStaticBitmap *static_bitmap = new wxStaticBitmap(this, wxID_ANY, bitmap);
//static_bitmap->SetSize(wxSize(20, 20));
//static_bitmap->SetMinSize(wxSize(100, 100));
content_sizer->Add(static_bitmap, 0, wxALL | wxALIGN_CENTER);
wxBoxSizer *row_sizer = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *hbox1 = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *hbox2 = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *vbox1 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *vbox2 = new wxBoxSizer(wxVERTICAL);
vbox1->Add(static_bitmap, 0, wxALL | wxALIGN_CENTER);
// Add add.svg image
//wxBitmap add_bitmap(*get_bmp_bundle("add.svg"), wxBITMAP_TYPE_SVG);
wxStaticBitmap *add_bitmap = new wxStaticBitmap(this, wxID_ANY, *get_bmp_bundle("print_time", 20));
@@ -109,50 +118,199 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path & path,
wxStaticText *total_weight_text = new wxStaticText(this, wxID_ANY, wxString::Format("%.4fg", ps.total_weight));
row_sizer->Add(total_weight_text, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
content_sizer->Add(row_sizer, 0, wxALIGN_CENTER);
vbox1->Add(row_sizer, 0, wxALIGN_CENTER);
//B61
content_sizer->Add(label_dir_hint2);
content_sizer->Add(txt_filename, 0, wxEXPAND);
content_sizer->Add(label_dir_hint);
content_sizer->AddSpacer(VERT_SPACING);
vbox2->Add(label_dir_hint2);
vbox2->Add(txt_filename, 0, wxEXPAND);
vbox2->Add(label_dir_hint);
vbox2->AddSpacer(VERT_SPACING);
auto *label_input_max_send = new wxStaticText(this, wxID_ANY, _L("(It depends on how many devices can undergo heating at the same time.)"));
label_input_max_send->Wrap(CONTENT_WIDTH * wxGetApp().em_unit());
auto *label_input_sending_interval = new wxStaticText(this, wxID_ANY, _L("(It depends on how long it takes to complete the heating.)"));
label_input_sending_interval->Wrap(CONTENT_WIDTH * wxGetApp().em_unit());
wxBoxSizer *max_printer_send =
create_item_input(_L("Send"),
_L("printers at the same time."), this,
"", "max_send");
vbox2->Add(max_printer_send);
vbox2->Add(label_input_max_send);
vbox2->Add(0, 0, 0, wxEXPAND | wxTOP, 23);
wxBoxSizer *delay_time = create_item_input(_L("Wait"),
_L("minute each batch."),
this, "", "sending_interval");
vbox2->Add(delay_time);
vbox2->Add(label_input_sending_interval);
hbox1->Add(vbox1);
hbox1->Add(0, 0, 0, wxEXPAND | wxLEFT, 23);
hbox1->Add(vbox2);
content_sizer->Add(0, 0, 0, wxEXPAND | wxTOP, 23);
content_sizer->Add(hbox1);
content_sizer->Add(0, 0, 0, wxEXPAND | wxTOP, 23);
//B53
wxBoxSizer * checkbox_sizer = new wxBoxSizer(wxVERTICAL);
PresetBundle & preset_bundle = *wxGetApp().preset_bundle;
wxButton* select_all_btn = new wxButton(this, wxID_ANY, _L("Select All"));
wxGetApp().SetWindowVariantForButton(select_all_btn);
checkbox_sizer->Add(select_all_btn, 0, wxEXPAND | wxALL, 5);
select_all_btn->Bind(wxEVT_BUTTON, [checkbox_sizer](wxCommandEvent &event) {
for (int i = 0; i < checkbox_sizer->GetItemCount(); i++) {
wxCheckBox *checkbox = dynamic_cast<wxCheckBox *>(checkbox_sizer->GetItem(i)->GetWindow());
if (checkbox) {
checkbox->SetValue(true);
}
}
});
wxScrolledWindow *scroll_macine_list = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(800), FromDIP(300)),
wxHSCROLL | wxVSCROLL);
scroll_macine_list->SetBackgroundColour(*wxWHITE);
scroll_macine_list->SetScrollRate(5, 5);
scroll_macine_list->SetMinSize(wxSize(FromDIP(320), 10 * FromDIP(30)));
scroll_macine_list->SetMaxSize(wxSize(FromDIP(320), 10 * FromDIP(30)));
wxBoxSizer *sizer_machine_list = new wxBoxSizer(wxVERTICAL);
scroll_macine_list->SetSizer(sizer_machine_list);
scroll_macine_list->Layout();
//B64
const PhysicalPrinterCollection & ph_printers = preset_bundle.physical_printers;
std::vector<PhysicalPrinterPresetData> preset_data;
for (PhysicalPrinterCollection::ConstIterator it = ph_printers.begin(); it != ph_printers.end(); ++it) {
for (const std::string &preset_name : it->get_preset_names()) {
Preset *preset = wxGetApp().preset_bundle->printers.find_preset(preset_name);
if (preset != nullptr) {
//B62
preset_data.push_back({wxString::FromUTF8(it->get_full_name(preset_name)).Lower(), wxString::FromUTF8(preset_name),
wxString::FromUTF8(it->get_full_name(preset_name)), ph_printers.is_selected(it, preset_name),
preset_name
wxStringTokenizer tokenizer(wxString::FromUTF8(it->get_full_name(preset_name)), "*");
wxString tokenTemp = tokenizer.GetNextToken().Trim();
std::string tem_name = into_u8(tokenTemp);
auto * printer = preset_bundle.physical_printers.find_printer(tem_name);
wxString host = "";
DynamicPrintConfig *cfg_t = nullptr;
if (printer != nullptr) {
host = (printer->config.opt_string("print_host"));
cfg_t = &(printer->config);
}
//B62 // y1
preset_data.push_back({from_u8(it->get_full_name(preset_name)).Lower(), from_u8(preset_name),
from_u8(it->get_full_name(preset_name)), ph_printers.is_selected(it, preset_name),
preset_name, host, cfg_t
});
}
}
}
m_presetData = preset_data;
for (const PhysicalPrinterPresetData &data : preset_data) {
wxCheckBox *checkbox = new wxCheckBox(this, wxID_ANY, _L(data.fullname));
wxCheckBox *checkbox = new wxCheckBox(scroll_macine_list, wxID_ANY, " " + data.fullname + "\n IP: " + data.host);
checkbox->SetValue(data.selected);
checkbox_sizer->Add(checkbox, 0, wxEXPAND | wxALL, 5);
sizer_machine_list->Add(checkbox, 0, wxEXPAND | wxALL, 5);
}
content_sizer->Add(checkbox_sizer);
wxBoxSizer *scrool_box_sizer = new wxBoxSizer(wxVERTICAL);
wxPanel *panel = new wxPanel(this, wxID_ANY);
panel->SetBackgroundColour(*wxWHITE);
wxBoxSizer *box_sizer = new wxBoxSizer(wxHORIZONTAL);
panel->SetSizer(box_sizer);
wxCheckBox *selectcheckbox = new wxCheckBox(panel, wxID_ANY, "");
selectcheckbox->Bind(wxEVT_CHECKBOX, [sizer_machine_list](wxCommandEvent &event) {
bool isChecked = event.IsChecked();
for (int i = 0; i < sizer_machine_list->GetItemCount(); i++) {
wxCheckBox *checkbox = dynamic_cast<wxCheckBox *>(sizer_machine_list->GetItem(i)->GetWindow());
if (checkbox) {
checkbox->SetValue(isChecked);
}
}
});
wxStaticText *text = new wxStaticText(panel, wxID_ANY, _L("QIDI Slicer's Physical Printer"));
text->SetWindowStyle(wxALIGN_CENTER_HORIZONTAL);
box_sizer->Add(selectcheckbox, 0, wxEXPAND | wxALL, 5);
box_sizer->Add(text, 0, wxEXPAND | wxALL, 5);
wxStaticLine *line = new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
line->SetForegroundColour(wxColour(220, 220, 220));
scrool_box_sizer->Add(panel, 0, wxEXPAND);
scrool_box_sizer->Add(line, 0, wxEXPAND | wxTOP | wxBOTTOM, 5);
scrool_box_sizer->Add(scroll_macine_list);
wxScrolledWindow *scroll_macine_list2 = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(800), FromDIP(300)),
wxHSCROLL | wxVSCROLL);
scroll_macine_list2->SetBackgroundColour(*wxWHITE);
scroll_macine_list2->SetScrollRate(5, 5);
scroll_macine_list2->SetMinSize(wxSize(FromDIP(320), 10 * FromDIP(30)));
scroll_macine_list2->SetMaxSize(wxSize(FromDIP(320), 10 * FromDIP(30)));
wxBoxSizer *sizer_machine_list2 = new wxBoxSizer(wxVERTICAL);
scroll_macine_list2->SetSizer(sizer_machine_list2);
scroll_macine_list2->Layout();
#if QDT_RELEASE_TO_PUBLIC
auto m_devices = wxGetApp().get_devices();
for (const auto &device : m_devices) {
wxCheckBox *checkbox = new wxCheckBox(scroll_macine_list2, wxID_ANY, " " + from_u8(device.device_name) + "\n IP: " + device.local_ip);
checkbox->SetValue(false);
sizer_machine_list2->Add(checkbox, 0, wxEXPAND | wxALL, 5);
}
#endif
wxBoxSizer *scrool_box_sizer2 = new wxBoxSizer(wxVERTICAL);
wxPanel *panel2 = new wxPanel(this, wxID_ANY);
panel2->SetBackgroundColour(*wxWHITE);
wxBoxSizer *box_sizer2 = new wxBoxSizer(wxHORIZONTAL);
panel2->SetSizer(box_sizer2);
wxCheckBox *selectcheckbox2 = new wxCheckBox(panel2, wxID_ANY, "");
selectcheckbox2->Bind(wxEVT_CHECKBOX, [sizer_machine_list2](wxCommandEvent &event) {
bool isChecked = event.IsChecked();
for (int i = 0; i < sizer_machine_list2->GetItemCount(); i++) {
wxCheckBox *checkbox = dynamic_cast<wxCheckBox *>(sizer_machine_list2->GetItem(i)->GetWindow());
if (checkbox) {
checkbox->SetValue(isChecked);
}
}
});
wxStaticText *text2 = new wxStaticText(panel2, wxID_ANY, _L("QIDI Link's Physical Printer"));
text2->SetWindowStyle(wxALIGN_CENTER_HORIZONTAL);
box_sizer2->Add(selectcheckbox2, 0, wxEXPAND | wxALL, 5);
box_sizer2->Add(text2, 0, wxEXPAND | wxALL, 5);
wxStaticLine *line2 = new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
line2->SetForegroundColour(wxColour(220, 220, 220));
scrool_box_sizer2->Add(panel2, 0, wxEXPAND);
scrool_box_sizer2->Add(line2, 0, wxEXPAND | wxTOP | wxBOTTOM, 5);
scrool_box_sizer2->Add(scroll_macine_list2);
wxStaticBoxSizer *sizer1 = new wxStaticBoxSizer(wxVERTICAL, this, _L(""));
sizer1->Add(scrool_box_sizer, 1, wxEXPAND | wxALL, 10);
wxStaticBoxSizer *sizer2 = new wxStaticBoxSizer(wxVERTICAL, this, _L(""));
sizer2->Add(scrool_box_sizer2, 1, wxEXPAND | wxALL, 10);
//hbox2->Add(scrool_box_sizer);
//hbox2->Add(0, 0, 0, wxEXPAND | wxLEFT, 23);
//hbox2->Add(scrool_box_sizer2);
hbox2->Add(sizer1, 1, wxEXPAND);
hbox2->Add(0, 0, 0, wxEXPAND | wxLEFT, 23);
hbox2->Add(sizer2, 1, wxEXPAND);
content_sizer->Add(hbox2 , 1, wxEXPAND);
content_sizer->Add(0, 0, 0, wxEXPAND | wxBOTTOM, 23);
if (combo_groups != nullptr) {
// Repetier specific: Show a selection of file groups.
@@ -203,19 +361,28 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path & path,
return true;
};
//B53
//B53 //B64
auto* btn_ok = add_button(wxID_OK, false, _L("Upload"));
btn_ok->Bind(wxEVT_BUTTON, [this, validate_path, checkbox_sizer](wxCommandEvent &) {
btn_ok->Bind(wxEVT_BUTTON, [this, validate_path, sizer_machine_list, sizer_machine_list2](wxCommandEvent &) {
if (validate_path(txt_filename->GetValue())) {
std::vector<bool> checkbox_states;
for (int i = 0; i < checkbox_sizer->GetItemCount(); i++) {
wxCheckBox *checkbox = dynamic_cast<wxCheckBox *>(checkbox_sizer->GetItem(i)->GetWindow());
for (int i = 0; i < sizer_machine_list->GetItemCount(); i++) {
wxCheckBox *checkbox = dynamic_cast<wxCheckBox *>(sizer_machine_list->GetItem(i)->GetWindow());
if (checkbox) {
checkbox_states.push_back(checkbox->GetValue());
}
}
m_checkbox_states = checkbox_states;
checkbox_states.clear();
for (int i = 0; i < sizer_machine_list2->GetItemCount(); i++) {
wxCheckBox *checkbox = dynamic_cast<wxCheckBox *>(sizer_machine_list2->GetItem(i)->GetWindow());
if (checkbox) {
checkbox_states.push_back(checkbox->GetValue());
}
}
m_checkbox_net_states = checkbox_states;
post_upload_action = PrintHostPostUploadAction::None;
EndDialog(wxID_OK);
}
@@ -223,10 +390,17 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path & path,
txt_filename->SetFocus();
//B53
Bind(wxEVT_CHECKBOX, [btn_ok, checkbox_sizer, this](wxCommandEvent &event) {
Bind(wxEVT_CHECKBOX, [btn_ok, sizer_machine_list, sizer_machine_list2, this](wxCommandEvent &event) {
bool any_checkbox_selected = false;
for (int i = 0; i < checkbox_sizer->GetItemCount(); i++) {
wxCheckBox *checkbox = dynamic_cast<wxCheckBox *>(checkbox_sizer->GetItem(i)->GetWindow());
for (int i = 0; i < sizer_machine_list->GetItemCount(); i++) {
wxCheckBox *checkbox = dynamic_cast<wxCheckBox *>(sizer_machine_list->GetItem(i)->GetWindow());
if (checkbox && checkbox->GetValue()) {
any_checkbox_selected = true;
break;
}
}
for (int i = 0; i < sizer_machine_list2->GetItemCount(); i++) {
wxCheckBox *checkbox = dynamic_cast<wxCheckBox *>(sizer_machine_list2->GetItem(i)->GetWindow());
if (checkbox && checkbox->GetValue()) {
any_checkbox_selected = true;
break;
@@ -244,29 +418,46 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path & path,
});
}
//B53
//B53 //B64
if (post_actions.has(PrintHostPostUploadAction::StartPrint)) {
auto* btn_print = add_button(wxID_YES, false, _L("Upload and Print"));
btn_print->Bind(wxEVT_BUTTON, [this, validate_path, checkbox_sizer](wxCommandEvent &) {
btn_print->Bind(wxEVT_BUTTON, [this, validate_path, sizer_machine_list, sizer_machine_list2](wxCommandEvent &) {
if (validate_path(txt_filename->GetValue())) {
std::vector<bool> checkbox_states;
for (int i = 0; i < checkbox_sizer->GetItemCount(); i++) {
wxCheckBox *checkbox = dynamic_cast<wxCheckBox *>(checkbox_sizer->GetItem(i)->GetWindow());
for (int i = 0; i < sizer_machine_list->GetItemCount(); i++) {
wxCheckBox *checkbox = dynamic_cast<wxCheckBox *>(sizer_machine_list->GetItem(i)->GetWindow());
if (checkbox) {
checkbox_states.push_back(checkbox->GetValue());
}
}
m_checkbox_states = checkbox_states;
checkbox_states.clear();
for (int i = 0; i < sizer_machine_list2->GetItemCount(); i++) {
wxCheckBox *checkbox = dynamic_cast<wxCheckBox *>(sizer_machine_list2->GetItem(i)->GetWindow());
if (checkbox) {
checkbox_states.push_back(checkbox->GetValue());
}
}
m_checkbox_net_states = checkbox_states;
post_upload_action = PrintHostPostUploadAction::StartPrint;
EndDialog(wxID_OK);
}
});
//B53
Bind(wxEVT_CHECKBOX, [btn_ok,btn_print, checkbox_sizer, this](wxCommandEvent &event) {
//B53 //B64
Bind(wxEVT_CHECKBOX, [btn_ok, btn_print, sizer_machine_list, sizer_machine_list2, this](wxCommandEvent &event) {
bool any_checkbox_selected = false;
for (int i = 0; i < checkbox_sizer->GetItemCount(); i++) {
wxCheckBox *checkbox = dynamic_cast<wxCheckBox *>(checkbox_sizer->GetItem(i)->GetWindow());
for (int i = 0; i < sizer_machine_list->GetItemCount(); i++) {
wxCheckBox *checkbox = dynamic_cast<wxCheckBox *>(sizer_machine_list->GetItem(i)->GetWindow());
if (checkbox && checkbox->GetValue()) {
any_checkbox_selected = true;
break;
}
}
for (int i = 0; i < sizer_machine_list2->GetItemCount(); i++) {
wxCheckBox *checkbox = dynamic_cast<wxCheckBox *>(sizer_machine_list2->GetItem(i)->GetWindow());
if (checkbox && checkbox->GetValue()) {
any_checkbox_selected = true;
break;
@@ -340,7 +531,54 @@ std::string PrintHostSendDialog::storage() const
return {};
return boost::nowide::narrow(m_paths[combo_storage->GetSelection()]);
}
//B64
wxBoxSizer *PrintHostSendDialog::create_item_input(
wxString str_before, wxString str_after, wxWindow *parent, wxString tooltip, std::string param)
{
wxBoxSizer *sizer_input = new wxBoxSizer(wxHORIZONTAL);
auto input_title = new wxStaticText(parent, wxID_ANY, str_before);
input_title->SetForegroundColour(wxColour(38, 46, 48));
input_title->SetFont(::Label::Body_13);
input_title->SetToolTip(tooltip);
input_title->Wrap(-1);
auto input = new ::TextInput(parent, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(50), -1),
wxTE_PROCESS_ENTER);
StateColor input_bg(std::pair<wxColour, int>(wxColour("#F0F0F1"), StateColor::Disabled),
std::pair<wxColour, int>(*wxWHITE, StateColor::Enabled));
input->SetBackgroundColor(input_bg);
input->GetTextCtrl()->SetValue(wxGetApp().app_config->get(param));
wxTextValidator validator(wxFILTER_DIGITS);
input->GetTextCtrl()->SetValidator(validator);
auto second_title = new wxStaticText(parent, wxID_ANY, str_after, wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
second_title->SetForegroundColour(wxColour(38, 46, 48));
second_title->SetFont(::Label::Body_13);
second_title->SetToolTip(tooltip);
second_title->Wrap(-1);
//sizer_input->Add(0, 0, 0, wxEXPAND | wxLEFT, 23);
sizer_input->Add(input_title, 0, wxALIGN_CENTER_VERTICAL | wxALL, 3);
sizer_input->Add(input, 0, wxALIGN_CENTER_VERTICAL, 0);
sizer_input->Add(0, 0, 0, wxEXPAND | wxLEFT, 3);
sizer_input->Add(second_title, 0, wxALIGN_CENTER_VERTICAL | wxALL, 3);
input->GetTextCtrl()->Bind(wxEVT_TEXT_ENTER, [this, param, input](wxCommandEvent &e) {
auto value = input->GetTextCtrl()->GetValue();
wxGetApp().app_config->set(param, std::string(value.mb_str()));
wxGetApp().app_config->save();
e.Skip();
});
input->GetTextCtrl()->Bind(wxEVT_KILL_FOCUS, [this, param, input](wxFocusEvent &e) {
auto value = input->GetTextCtrl()->GetValue();
wxGetApp().app_config->set(param, std::string(value.mb_str()));
wxGetApp().app_config->save();
e.Skip();
});
return sizer_input;
}
void PrintHostSendDialog::EndModal(int ret)
{
if (ret == wxID_OK) {
@@ -367,6 +605,8 @@ void PrintHostSendDialog::EndModal(int ret)
MsgDialog::EndModal(ret);
}
//B64
wxDEFINE_EVENT(EVT_PRINTHOST_WAIT, PrintHostQueueDialog::Event);
wxDEFINE_EVENT(EVT_PRINTHOST_PROGRESS, PrintHostQueueDialog::Event);
wxDEFINE_EVENT(EVT_PRINTHOST_ERROR, PrintHostQueueDialog::Event);
@@ -384,6 +624,10 @@ PrintHostQueueDialog::Event::Event(wxEventType eventType, int winid, size_t job_
, progress(progress)
{}
//B64
PrintHostQueueDialog::Event::Event(wxEventType eventType, int winid, size_t job_id, int waittime, int progress)
: wxEvent(winid, eventType), job_id(job_id), waittime(waittime), progress(progress)
{}
PrintHostQueueDialog::Event::Event(wxEventType eventType, int winid, size_t job_id, wxString error)
: wxEvent(winid, eventType)
, job_id(job_id)
@@ -402,8 +646,10 @@ wxEvent *PrintHostQueueDialog::Event::Clone() const
return new Event(*this);
}
//B64
PrintHostQueueDialog::PrintHostQueueDialog(wxWindow *parent)
: DPIDialog(parent, wxID_ANY, _L("Print host upload queue"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
, on_wait_evt(this, EVT_PRINTHOST_WAIT, &PrintHostQueueDialog::on_wait, this)
, on_progress_evt(this, EVT_PRINTHOST_PROGRESS, &PrintHostQueueDialog::on_progress, this)
, on_error_evt(this, EVT_PRINTHOST_ERROR, &PrintHostQueueDialog::on_error, this)
, on_cancel_evt(this, EVT_PRINTHOST_CANCEL, &PrintHostQueueDialog::on_cancel, this)
@@ -606,13 +852,38 @@ void PrintHostQueueDialog::on_progress(Event &evt)
}
}
//B64
void PrintHostQueueDialog::on_wait(Event &evt)
{
wxCHECK_RET(evt.job_id < (size_t) job_list->GetItemCount(), "Out of bounds access to job list");
wxVariant nm, hst;
job_list->GetValue(nm, evt.job_id, COL_FILENAME);
job_list->GetValue(hst, evt.job_id, COL_HOST);
wxGetApp().notification_manager()->set_upload_job_notification_waittime(evt.job_id + 1, boost::nowide::narrow(nm.GetString()),
boost::nowide::narrow(hst.GetString()),
evt.waittime);
}
void PrintHostQueueDialog::on_error(Event &evt)
{
wxCHECK_RET(evt.job_id < (size_t)job_list->GetItemCount(), "Out of bounds access to job list");
set_state(evt.job_id, ST_ERROR);
auto errormsg = format_wxstr("%1%\n%2%", _L("Error uploading to print host") + ":", evt.status);
// y1
std::string response_msg = into_u8(evt.status);
size_t pos_404 = evt.status.find("HTTP 404:");
wxString code_msg = "";
if (pos_404 != std::string::npos) {
code_msg = _L("Network connection fails.");
size_t isAws = response_msg.find("AWS");
if(isAws != std::string::npos)
code_msg += _L("Unable to get required resources from AWS server, please check your network settings.");
else
code_msg += _L("Unable to get required resources from ESC server, please check your network settings.");
}
else
code_msg = _L("Network connection times out. Please check the device network Settings.");
auto errormsg = format_wxstr("%1%\n%2%", _L("Error uploading to print host") + ":", code_msg);
job_list->SetValue(wxVariant(0), evt.job_id, COL_PROGRESS);
job_list->SetValue(wxVariant(errormsg), evt.job_id, COL_ERRORMSG); // Stashes the error message into a hidden column for later

View File

@@ -34,7 +34,8 @@ struct PhysicalPrinterPresetData
wxString fullname; // full name
bool selected; // is selected
std::string preset_name;
int checkboxId;
wxString host;
DynamicPrintConfig *cfg_t;
};
class PrintHostSendDialog : public GUI::MsgDialog
{
@@ -55,7 +56,12 @@ public:
std::vector<PhysicalPrinterPresetData> pppd() { return m_presetData; }
std::vector<bool> checkbox_states() { return m_checkbox_states; }
//B64
std::vector<bool> checkbox_net_states() { return m_checkbox_net_states; }
virtual void EndModal(int ret) override;
//B64
wxBoxSizer *create_item_input(
wxString str_before, wxString str_after, wxWindow *parent, wxString tooltip, std::string param);
private:
wxTextCtrl *txt_filename;
wxComboBox *combo_groups;
@@ -67,6 +73,8 @@ private:
//B53
std::vector<PhysicalPrinterPresetData> m_presetData;
std::vector<bool> m_checkbox_states;
//B64
std::vector<bool> m_checkbox_net_states;
//B61
Plater *m_plater{nullptr};
};
@@ -82,11 +90,15 @@ public:
int progress = 0; // in percent
wxString tag;
wxString status;
//B64
int waittime = 0;
Event(wxEventType eventType, int winid, size_t job_id);
Event(wxEventType eventType, int winid, size_t job_id, int progress);
Event(wxEventType eventType, int winid, size_t job_id, wxString error);
Event(wxEventType eventType, int winid, size_t job_id, wxString tag, wxString status);
//B64
Event(wxEventType eventType, int winid, size_t job_id, int waittime,int progress);
virtual wxEvent *Clone() const;
};
@@ -139,6 +151,8 @@ private:
wxButton *btn_error;
wxDataViewListCtrl *job_list;
// Note: EventGuard prevents delivery of progress evts to a freed PrintHostQueueDialog
//B64
EventGuard on_wait_evt;
EventGuard on_progress_evt;
EventGuard on_error_evt;
EventGuard on_cancel_evt;
@@ -148,6 +162,8 @@ private:
void set_state(int idx, JobState);
void on_list_select();
void on_progress(Event&);
//B64
void on_wait(Event &);
void on_error(Event&);
void on_cancel(Event&);
void on_info(Event&);
@@ -157,6 +173,8 @@ private:
bool load_user_data(int, std::vector<int>&);
};
//B64
wxDECLARE_EVENT(EVT_PRINTHOST_WAIT, PrintHostQueueDialog::Event);
wxDECLARE_EVENT(EVT_PRINTHOST_PROGRESS, PrintHostQueueDialog::Event);
wxDECLARE_EVENT(EVT_PRINTHOST_ERROR, PrintHostQueueDialog::Event);
wxDECLARE_EVENT(EVT_PRINTHOST_CANCEL, PrintHostQueueDialog::Event);

File diff suppressed because it is too large Load Diff

View File

@@ -38,205 +38,14 @@
#include "PrintHostDialogs.hpp"
#include <wx/tokenzr.h>
//B64
#include "../Utils/QIDINetwork.hpp"
#include <boost/thread.hpp>
#include "./Widgets/SwitchButton.hpp"
#include "./Widgets/DeviceButton.hpp"
namespace Slic3r {
namespace GUI {
class MachineListButton : public wxButton
{
public:
MachineListButton(wxWindow * parent,
wxWindowID id,
const wxString & label,
const wxString &fullname,
const wxPoint & pos = wxDefaultPosition,
const wxSize & size = wxDefaultSize,
long style = wxBORDER_DOUBLE,
const wxValidator &validator = wxDefaultValidator,
const wxString & name = wxButtonNameStr,
bool isSelected = false)
: wxButton(parent, id, label, pos, size, style, validator, name)
{
SetBackgroundColour(wxColour(30, 30, 32));
full_label = fullname;
m_isSelected = isSelected;
//if (isSelected)
// SetBackgroundColour(wxColour(100, 100, 105));
//else
// SetBackgroundColour(wxColour(67, 67, 71));
#if defined(__WIN32__) || defined(__WXMAC__)
SetBackgroundColour(wxColour(30, 30, 32));
#else
if (isSelected)
SetBackgroundColour(wxColour(100, 100, 105));
else
SetBackgroundColour(wxColour(67, 67, 71));
#endif
Bind(wxEVT_PAINT, &MachineListButton::OnPaint, this);
Bind(wxEVT_ENTER_WINDOW, &MachineListButton::OnMouseEnter, this);
Bind(wxEVT_LEAVE_WINDOW, &MachineListButton::OnMouseLeave, this);
Bind(wxEVT_SET_FOCUS, &MachineListButton::OnSetFocus, this);
Bind(wxEVT_KILL_FOCUS, &MachineListButton::OnKillFocus, this);
Bind(wxEVT_KEY_DOWN, &MachineListButton::OnKeyDown, this);
//Bind(wxEVT_KEY_UP, &MachineListButton::OnKeyUp, this);
}
void SetLabel(const wxString &fullname) { full_label = fullname; }
wxString getLabel() { return full_label; }
wxString getIPLabel() { return m_ip_text; }
bool getIsQIDI() { return m_is_QIDI; }
void SetBitMap(const wxBitmap &bitmap)
{
m_bitmap = bitmap;
Refresh();
}
void SetNameText(const wxString &text)
{
m_name_text = text;
Refresh();
}
//B59
void SetIsQIDI(const bool &text)
{
m_is_QIDI = text;
//Refresh();
}
wxString GetNameText()
{
return m_name_text;
}
void SetIPText(const wxString &text)
{
m_ip_text = text;
Refresh();
}
void SetStateText(const wxString &text)
{
m_state_text = text;
Refresh();
}
void SetProgressText(const wxString &text)
{
m_progress_text = text;
Refresh();
}
void SetSelect(bool isselectd)
{
m_isSelected = isselectd;
#if defined(__WIN32__) || defined(__WXMAC__)
SetBackgroundColour(wxColour(30, 30, 32));
#else
if (m_isSelected)
SetBackgroundColour(wxColour(100, 100, 105));
else
SetBackgroundColour(wxColour(67, 67, 71));
#endif
Refresh();
}
bool GetSelected() { return m_isSelected;}
void SetSimpleMode(bool issimplemode)
{
m_isSimpleMode = issimplemode;
Refresh();
}
void SetClickHandler(const std::function<void(wxMouseEvent &)> &handler) { m_handlerl = handler; }
void PauseStatusThread() { m_pauseThread = true; }
void ResumeStatusThread() { m_pauseThread = false; }
void StopStatusThread()
{
m_stopThread = true;
if (m_statusThread.joinable()) {
m_statusThread.join();
}
}
void OnPaint(wxPaintEvent &event);
void OnSetFocus(wxFocusEvent &event);
void OnKillFocus(wxFocusEvent &event);
void OnKeyDown(wxKeyEvent &event);
void OnKeyUp(wxKeyEvent &event);
void OnMouseEnter(wxMouseEvent &event);
void OnMouseLeave(wxMouseEvent &event);
//void OnMouseLeftDown(wxMouseEvent &event);
//void OnMouseLeftUp(wxMouseEvent &event);
//void OnClickHandler(wxCommandEvent &event);
void SetStatusThread(std::thread thread) { m_statusThread = std::move(thread); }
std::thread CreatThread(const wxString &buttonText, const wxString &ip, DynamicPrintConfig *cfg_t)
{
std::thread thread([this, buttonText,ip, cfg_t]() {
std::unique_ptr<PrintHost> printhost(PrintHost::get_print_host(cfg_t));
if (!printhost) {
BOOST_LOG_TRIVIAL(error) << ("Could not get a valid Printer Host reference");
return;
}
wxString msg;
std::string state = "standby";
float progress = 0;
int timeout_times = 0;
while (true) {
if (!m_pauseThread) {
state = printhost->get_status(msg);
if (state == "offline") {
BOOST_LOG_TRIVIAL(info) << boost::format("%1%Got state: %2%") % buttonText % state;
timeout_times += 1;
if (timeout_times>3)
m_pauseThread = true;
}
BOOST_LOG_TRIVIAL(info) << boost::format("%1%Got state: %2%") % buttonText % state;
if (m_state_text != state)
SetStateText(state);
if (state == "printing") {
timeout_times = 0;
progress = (printhost->get_progress(msg)) * 100;
int progressInt = static_cast<int>(progress);
SetProgressText(wxString::Format(wxT("(%d%%)"), progressInt));
BOOST_LOG_TRIVIAL(info) << boost::format("%1%Got progress: %2%") % buttonText % progress;
} else if (state == "standby")
timeout_times = 0;
}
if (m_stopThread)
break;
}
});
return thread;
}
private:
std::atomic<bool> m_stopThread{false};
std::atomic<bool> m_pauseThread{false};
bool m_isSimpleMode;
bool m_isSelected = false;
bool m_isHovered = false;
//bool m_isClicked = false;
std::thread m_statusThread;
//wxGraphicsContext *gc;
wxPaintDC * m_dc;
wxBitmap m_bitmap;
wxString full_label;
wxString m_name_text;
wxString m_ip_text;
wxString m_state_text;
wxString m_progress_text;
std::function<void(wxMouseEvent &)> m_handlerl;
//B59
bool m_is_QIDI;
//wxDECLARE_EVENT_TABLE();
};
@@ -246,18 +55,22 @@ public:
PrinterWebView(wxWindow *parent);
virtual ~PrinterWebView();
wxBoxSizer *init_menu_bar(wxPanel *Panel);
wxBoxSizer *init_login_bar(wxPanel *Panel);
void init_scroll_window(wxPanel *Panel);
void CreatThread();
void load_url(wxString& url);
void load_net_url(std::string url, std::string ip);
void UpdateState();
void OnClose(wxCloseEvent& evt);
//B45
void OnLeftButtonClick(wxCommandEvent &event);
void OnRightButtonClick(wxCommandEvent &event);
void OnCustomButtonClick(std::function<void(wxCommandEvent &)> m_handler, wxCommandEvent &event);
void OnZoomButtonClick(wxCommandEvent &event);
void OnRefreshButtonClick(wxCommandEvent &event);
void OnAddButtonClick(wxCommandEvent &event);
void OnDeleteButtonClick(wxCommandEvent &event);
void OnEditButtonClick(wxCommandEvent &event);
void OnLoginButtonClick(wxCommandEvent &event);
void RunScript(const wxString &javascript);
//void OnScriptMessageReceived(wxWebViewEvent &event);
void OnScriptMessage(wxWebViewEvent &evt);
@@ -265,41 +78,47 @@ public:
void OnScroll(wxScrollWinEvent &event);
void OnScrollup(wxScrollWinEvent &event);
void OnScrolldown(wxScrollWinEvent &event);
//B63
void OnKeyUp(wxKeyEvent &event);
void SetUpdateHandler(const std::function<void(wxCommandEvent &)> &handler) { m_handlerl = handler; }
void SetDeleteHandler(const std::function<void(wxCommandEvent &)> &handler) { m_delete_handlerl = handler; }
//B45
//void SendRecentList(int images);
void SetButtons(std::vector<MachineListButton *> buttons);
//B55
void SetButtons(std::vector<DeviceButton *> buttons);
void AddButton(const wxString & device_name,
const wxString & ip,
const wxString & machine_type,
const wxString & fullname,
bool isSelected,
bool isQIDI,
DynamicPrintConfig * cfg_t);
bool isQIDI);
void DeleteButton();
void PauseButton();
void ResumeButton();
void StopAllThread();
void UnSelectedButton();
void ShowNetPrinterButton();
void ShowLocalPrinterButton();
#if QDT_RELEASE_TO_PUBLIC
void AddNetButton(const Device device);
#endif
//B63
void DeleteNetButton();
void RefreshButton();
std::vector<MachineListButton *> GetButton() { return m_buttons; };
void SetUpdateHandler(const std::function<void(wxCommandEvent &)> &handler) { m_handlerl = handler; }
void StopStatusThread()
{
m_stopThread = true;
if (m_statusThread.joinable()) {
m_statusThread.join();
}
};
void SetPauseThread(bool status) { m_pauseThread = status; };
void SetPresetChanged(bool status);
void SetLoginStatus(bool status);
std::vector<DeviceButton *> GetButton() { return m_buttons; };
bool GetNetMode() { return m_isNetMode; };
std::vector<DeviceButton *> GetNetButton() { return m_net_buttons; };
private:
//B45
wxBoxSizer *leftallsizer;
wxBoxSizer *leftsizer;
wxBoxSizer *topsizer;
wxBoxSizer * devicesizer;
wxBoxSizer * allsizer;
bool m_isSimpleMode = false;
bool m_isNetMode = false;
wxButton *arrow_button;
wxStaticText * text_static;
@@ -312,17 +131,24 @@ private:
wxPanel * leftPanel;
std::vector<MachineListButton *> m_buttons;
std::vector<DeviceButton *> m_buttons;
std::vector<DeviceButton *> m_net_buttons;
std::string m_select_type;
std::thread m_statusThread;
std::atomic<bool> m_stopThread{false};
std::atomic<bool> m_pauseThread{true};
wxWebView* m_browser;
long m_zoomFactor;
//B63
MachineListButton *add_button;
MachineListButton *delete_button;
MachineListButton *edit_button;
MachineListButton *refresh_button;
// DECLARE_EVENT_TABLE()
DeviceButton * add_button;
DeviceButton * delete_button;
DeviceButton * edit_button;
DeviceButton * refresh_button;
DeviceButton * login_button;
bool m_isloginin;
SwitchButton * toggleBar;
wxStaticBitmap * staticBitmap;
};

View File

@@ -0,0 +1,333 @@
#include "WebUserLoginDialog.hpp"
#include <string.h>
#include "I18N.hpp"
#include "libslic3r/AppConfig.hpp"
#include "slic3r/GUI/wxExtensions.hpp"
#include "slic3r/GUI/GUI_App.hpp"
#include "libslic3r_version.h"
#include <wx/sizer.h>
#include <wx/toolbar.h>
#include <wx/textdlg.h>
#include <wx/wx.h>
#include <wx/fileconf.h>
#include <wx/file.h>
#include <wx/wfstream.h>
#include <boost/cast.hpp>
#include <boost/lexical_cast.hpp>
#include "MainFrame.hpp"
#include <boost/dll.hpp>
#include <sstream>
#include <slic3r/GUI/Widgets/WebView.hpp>
#include "../Utils/QIDINetwork.hpp"
#include <nlohmann/json.hpp>
using namespace std;
using namespace nlohmann;
namespace Slic3r { namespace GUI {
#define NETWORK_OFFLINE_TIMER_ID 10001
BEGIN_EVENT_TABLE(ZUserLogin, wxDialog)
EVT_TIMER(NETWORK_OFFLINE_TIMER_ID, ZUserLogin::OnTimer)
END_EVENT_TABLE()
int ZUserLogin::web_sequence_id = 20000;
ZUserLogin::ZUserLogin() : wxDialog((wxWindow *) (wxGetApp().mainframe), wxID_ANY, "QIDIStudio")
{
SetBackgroundColour(*wxWHITE);
TargetUrl = "";
#if QDT_RELEASE_TO_PUBLIC
wxString msg;
QIDINetwork m_qidinetwork;
TargetUrl = m_qidinetwork.get_qidi_host();
#endif
BOOST_LOG_TRIVIAL(error) << "login url = " << TargetUrl.ToStdString();
m_qdt_user_agent = wxString::Format("QDT-Slicer/v%s", SLIC3R_VERSION);
// set the frame icon
// Create the webview
m_browser = WebView::CreateWebView(this, TargetUrl);
if (m_browser == nullptr) {
wxLogError("Could not init m_browser");
return;
}
m_browser->Hide();
m_browser->SetSize(0, 0);
Bind(wxEVT_WEBVIEW_NAVIGATING, &ZUserLogin::OnNavigationRequest, this, m_browser->GetId());
Bind(wxEVT_WEBVIEW_NAVIGATED, &ZUserLogin::OnNavigationComplete, this, m_browser->GetId());
Bind(wxEVT_WEBVIEW_LOADED, &ZUserLogin::OnDocumentLoaded, this, m_browser->GetId());
Bind(wxEVT_WEBVIEW_ERROR, &ZUserLogin::OnError, this, m_browser->GetId());
Bind(wxEVT_WEBVIEW_NEWWINDOW, &ZUserLogin::OnNewWindow, this, m_browser->GetId());
Bind(wxEVT_WEBVIEW_TITLE_CHANGED, &ZUserLogin::OnTitleChanged, this, m_browser->GetId());
Bind(wxEVT_WEBVIEW_FULLSCREEN_CHANGED, &ZUserLogin::OnFullScreenChanged, this, m_browser->GetId());
Bind(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, &ZUserLogin::OnScriptMessage, this, m_browser->GetId());
// UI
SetTitle(_L("Login"));
wxSize pSize = FromDIP(wxSize(650, 840));
SetSize(pSize);
int screenheight = wxSystemSettings::GetMetric(wxSYS_SCREEN_Y, NULL);
int screenwidth = wxSystemSettings::GetMetric(wxSYS_SCREEN_X, NULL);
int MaxY = (screenheight - pSize.y) > 0 ? (screenheight - pSize.y) / 2 : 0;
wxPoint tmpPT((screenwidth - pSize.x) / 2, MaxY);
Move(tmpPT);
}
ZUserLogin::~ZUserLogin()
{
if (m_timer != NULL) {
m_timer->Stop();
delete m_timer;
m_timer = NULL;
}
}
void ZUserLogin::OnTimer(wxTimerEvent &event)
{
m_timer->Stop();
if (m_networkOk == false) {
ShowErrorPage();
}
}
bool ZUserLogin::run()
{
m_timer = new wxTimer(this, NETWORK_OFFLINE_TIMER_ID);
m_timer->Start(8000);
if (this->ShowModal() == wxID_OK) {
return true;
} else {
return false;
}
}
void ZUserLogin::load_url(wxString &url)
{
m_browser->LoadURL(url);
m_browser->SetFocus();
UpdateState();
}
/**
* Method that retrieves the current state from the web control and updates
* the GUI the reflect this current state.
*/
void ZUserLogin::UpdateState()
{
// SetTitle(m_browser->GetCurrentTitle());
}
void ZUserLogin::OnIdle(wxIdleEvent &WXUNUSED(evt))
{
if (m_browser->IsBusy()) {
wxSetCursor(wxCURSOR_ARROWWAIT);
} else {
wxSetCursor(wxNullCursor);
}
}
// void ZUserLogin::OnClose(wxCloseEvent& evt)
//{
// this->Hide();
//}
/**
* Callback invoked when there is a request to load a new page (for instance
* when the user clicks a link)
*/
void ZUserLogin::OnNavigationRequest(wxWebViewEvent &evt)
{
// wxLogMessage("%s", "Navigation request to '" + evt.GetURL() + "'(target='" + evt.GetTarget() + "')");
UpdateState();
}
/**
* Callback invoked when a navigation request was accepted
*/
void ZUserLogin::OnNavigationComplete(wxWebViewEvent &evt)
{
// wxLogMessage("%s", "Navigation complete; url='" + evt.GetURL() + "'");
m_browser->Show();
Layout();
UpdateState();
}
/**
* Callback invoked when a page is finished loading
*/
void ZUserLogin::OnDocumentLoaded(wxWebViewEvent &evt)
{
// Only notify if the document is the main frame, not a subframe
wxString tmpUrl = evt.GetURL();
UpdateState();
}
/**
* On new window, we veto to stop extra windows appearing
*/
void ZUserLogin::OnNewWindow(wxWebViewEvent &evt)
{
wxString flag = " (other)";
if (evt.GetNavigationAction() == wxWEBVIEW_NAV_ACTION_USER) {
flag = " (user)";
}
// wxLogMessage("%s", "New window; url='" + evt.GetURL() + "'" + flag);
// If we handle new window events then just load them in this window as we
// are a single window browser
m_browser->LoadURL(evt.GetURL());
UpdateState();
}
void ZUserLogin::OnTitleChanged(wxWebViewEvent &evt)
{
// SetTitle(evt.GetString());
// wxLogMessage("%s", "Title changed; title='" + evt.GetString() + "'");
}
void ZUserLogin::OnFullScreenChanged(wxWebViewEvent &evt)
{
// wxLogMessage("Full screen changed; status = %d", evt.GetInt());
ShowFullScreen(evt.GetInt() != 0);
}
void ZUserLogin::OnScriptMessage(wxWebViewEvent &evt)
{
wxString str_input = evt.GetString();
BOOST_LOG_TRIVIAL(error) << evt.GetString();
std::string token;
try {
json j = json::parse(into_u8(str_input));
token = j["data"]["token"];
} catch (std::exception &e) {
wxMessageBox(e.what(), "parse json failed", wxICON_WARNING);
Close();
}
BOOST_LOG_TRIVIAL(error) << token;
wxGetApp().app_config->set("user_token", token);
Close();
wxGetApp().SetOnlineLogin((token != ""));
////wxLogMessage("Script message received; value = %s, handler = %s", evt.GetString(), evt.GetMessageHandler());
}
void ZUserLogin::RunScript(const wxString &javascript)
{
// Remember the script we run in any case, so the next time the user opens
// the "Run Script" dialog box, it is shown there for convenient updating.
m_javascript = javascript;
if (!m_browser)
return;
WebView::RunScript(m_browser, javascript);
}
#if wxUSE_WEBVIEW_IE
void ZUserLogin::OnRunScriptObjectWithEmulationLevel(wxCommandEvent &WXUNUSED(evt))
{
wxWebViewIE::MSWSetModernEmulationLevel();
RunScript("function f(){var person = new Object();person.name = 'Foo'; \
person.lastName = 'Bar';return person;}f();");
wxWebViewIE::MSWSetModernEmulationLevel(false);
}
void ZUserLogin::OnRunScriptDateWithEmulationLevel(wxCommandEvent &WXUNUSED(evt))
{
wxWebViewIE::MSWSetModernEmulationLevel();
RunScript("function f(){var d = new Date('10/08/2017 21:30:40'); \
var tzoffset = d.getTimezoneOffset() * 60000; return \
new Date(d.getTime() - tzoffset);}f();");
wxWebViewIE::MSWSetModernEmulationLevel(false);
}
void ZUserLogin::OnRunScriptArrayWithEmulationLevel(wxCommandEvent &WXUNUSED(evt))
{
wxWebViewIE::MSWSetModernEmulationLevel();
RunScript("function f(){ return [\"foo\", \"bar\"]; }f();");
wxWebViewIE::MSWSetModernEmulationLevel(false);
}
#endif
/**
* Callback invoked when a loading error occurs
*/
void ZUserLogin::OnError(wxWebViewEvent &evt)
{
#define WX_ERROR_CASE(type) \
case type: category = #type; break;
wxString category;
switch (evt.GetInt()) {
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_CONNECTION);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_CERTIFICATE);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_AUTH);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_SECURITY);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_NOT_FOUND);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_REQUEST);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_USER_CANCELLED);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_OTHER);
}
if (evt.GetInt() == wxWEBVIEW_NAV_ERR_CONNECTION) {
if (m_timer != NULL)
m_timer->Stop();
if (m_networkOk == false)
ShowErrorPage();
}
// wxLogMessage("%s", "Error; url='" + evt.GetURL() + "', error='" +
// category + " (" + evt.GetString() + ")'");
// Show the info bar with an error
// m_info->ShowMessage(_L("An error occurred loading ") + evt.GetURL() +
// "\n" + "'" + category + "'", wxICON_ERROR);
UpdateState();
}
void ZUserLogin::OnScriptResponseMessage(wxCommandEvent &WXUNUSED(evt))
{
// if (!m_response_js.empty())
//{
// RunScript(m_response_js);
//}
// RunScript("This is a message to Web!");
// RunScript("postMessage(\"AABBCCDD\");");
}
bool ZUserLogin::ShowErrorPage()
{
wxString ErrortUrl = from_u8((boost::filesystem::path(resources_dir()) / "web\\login\\error.html").make_preferred().string());
load_url(ErrortUrl);
return true;
}
}} // namespace Slic3r::GUI

View File

@@ -0,0 +1,91 @@
#pragma once
#ifndef slic3r_ZWebUserLogin_HEAD_
#define slic3r_ZWebUserLogin_HEAD_
#include "wx/artprov.h"
#include "wx/cmdline.h"
#include "wx/notifmsg.h"
#include "wx/settings.h"
#include "wx/timer.h"
#include "wx/webview.h"
#if wxUSE_WEBVIEW_IE
#include "wx/msw/webview_ie.h"
#endif
#if wxUSE_WEBVIEW_EDGE
#include "wx/msw/webview_edge.h"
#endif
#include "wx/webviewarchivehandler.h"
#include "wx/webviewfshandler.h"
#include "wx/numdlg.h"
#include "wx/infobar.h"
#include "wx/filesys.h"
#include "wx/fs_arc.h"
#include "wx/fs_mem.h"
#include "wx/stdpaths.h"
#include <wx/frame.h>
#include <wx/tbarbase.h>
#include "wx/textctrl.h"
namespace Slic3r { namespace GUI {
class ZUserLogin : public wxDialog
{
public:
ZUserLogin();
virtual ~ZUserLogin();
void load_url(wxString &url);
std::string w2s(wxString sSrc);
void UpdateState();
void OnIdle(wxIdleEvent &evt);
// void OnClose(wxCloseEvent &evt);
void OnNavigationRequest(wxWebViewEvent &evt);
void OnNavigationComplete(wxWebViewEvent &evt);
void OnDocumentLoaded(wxWebViewEvent &evt);
void OnNewWindow(wxWebViewEvent &evt);
void OnError(wxWebViewEvent &evt);
void OnTitleChanged(wxWebViewEvent &evt);
void OnFullScreenChanged(wxWebViewEvent &evt);
void OnScriptMessage(wxWebViewEvent &evt);
void OnScriptResponseMessage(wxCommandEvent &evt);
void RunScript(const wxString &javascript);
bool m_networkOk;
bool ShowErrorPage();
bool run();
static int web_sequence_id;
private:
wxTimer *m_timer { nullptr };
void OnTimer(wxTimerEvent &event);
private:
wxString TargetUrl;
wxWebView *m_browser;
std::string m_AutotestToken;
#if wxUSE_WEBVIEW_IE
wxMenuItem *m_script_object_el;
wxMenuItem *m_script_date_el;
wxMenuItem *m_script_array_el;
#endif
// Last executed JavaScript snippet, for convenience.
wxString m_javascript;
wxString m_response_js;
wxString m_qdt_user_agent;
DECLARE_EVENT_TABLE()
};
}} // namespace Slic3r::GUI
#endif

View File

@@ -0,0 +1,419 @@
#include "DeviceButton.hpp"
#include <wx/dcgraph.h>
#include <wx/dc.h>
#include <wx/dcclient.h>
BEGIN_EVENT_TABLE(DeviceButton, StaticBox)
EVT_LEFT_DOWN(DeviceButton::mouseDown)
EVT_LEFT_UP(DeviceButton::mouseReleased)
EVT_MOUSE_CAPTURE_LOST(DeviceButton::mouseCaptureLost)
EVT_KEY_DOWN(DeviceButton::keyDownUp)
EVT_KEY_UP(DeviceButton::keyDownUp)
// catch paint events
EVT_PAINT(DeviceButton::paintEvent)
END_EVENT_TABLE()
/*
* Called by the system of by wxWidgets when the panel needs
* to be redrawn. You can also trigger this call by
* calling Refresh()/Update().
*/
DeviceButton::DeviceButton(wxString name_text, wxString ip_text) : paddingSize(10, 8), m_name_text(name_text), m_ip_text(ip_text)
{
background_color = StateColor(
std::make_pair(0xF0F0F0, (int) StateColor::Disabled),
std::make_pair(0x37EE7C, (int) StateColor::Hovered | StateColor::Checked),
std::make_pair(0x00AE42, (int) StateColor::Checked),
std::make_pair(*wxLIGHT_GREY, (int) StateColor::Hovered),
std::make_pair(0x262629, (int) StateColor::Normal));
text_color = StateColor(
std::make_pair(*wxLIGHT_GREY, (int) StateColor::Disabled),
std::make_pair(*wxBLACK, (int) StateColor::Normal));
}
DeviceButton::DeviceButton(wxWindow *parent,
wxString text,
wxString icon,
long style,
wxSize iconSize /* = wxSize(16, 16)*/,
wxString name_text,
wxString ip_text)
: DeviceButton(name_text,ip_text)
{
Create(parent, text, icon, style, iconSize);
}
bool DeviceButton::Create(wxWindow *parent, wxString text, wxString icon, long style, wxSize iconSize /* = wxSize(16, 16)*/)
{
StaticBox::Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, style);
state_handler.attach({&text_color});
state_handler.update_binds();
wxWindow::SetFont(wxFont(15, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD));
// y1
std::string test_string = text.ToStdString();
wxString device_nameText = wxString::FromUTF8(test_string);
wxWindow::SetLabel(device_nameText);
if (!icon.IsEmpty()) {
this->active_icon = ScalableBitmap(this, icon.ToStdString(), iconSize);
}
messureSize();
return true;
}
void DeviceButton::SetLabel(const wxString &label)
{
wxWindow::SetLabel(label);
messureSize();
Refresh();
}
void DeviceButton::SetIconWithSize(const wxString &icon, wxSize iconSize)
{
if (!icon.IsEmpty()) {
this->active_icon = ScalableBitmap(this, icon.ToStdString(), iconSize);
} else {
this->active_icon = ScalableBitmap();
}
messureSize();
Refresh();
}
void DeviceButton::SetIcon(const wxString &icon)
{
if (!icon.IsEmpty()) {
this->active_icon = ScalableBitmap(this, icon.ToStdString(), this->active_icon.px_size());
}
else
{
this->active_icon = ScalableBitmap();
}
Refresh();
}
void DeviceButton::SetInactiveIcon(const wxString &icon)
{
if (!icon.IsEmpty()) {
this->inactive_icon = ScalableBitmap(this, icon.ToStdString(), this->active_icon.px_size());
} else {
this->inactive_icon = ScalableBitmap();
}
Refresh();
}
void DeviceButton::SetMinSize(const wxSize &size)
{
minSize = size;
messureSize();
}
void DeviceButton::SetPaddingSize(const wxSize &size)
{
paddingSize = size;
messureSize();
}
void DeviceButton::SetTextColor(StateColor const &color)
{
text_color = color;
state_handler.update_binds();
Refresh();
}
void DeviceButton::SetTextColorNormal(wxColor const &color)
{
text_color.setColorForStates(color, 0);
Refresh();
}
bool DeviceButton::Enable(bool enable)
{
bool result = wxWindow::Enable(enable);
if (result) {
wxCommandEvent e(EVT_ENABLE_CHANGED);
e.SetEventObject(this);
GetEventHandler()->ProcessEvent(e);
}
return result;
}
void DeviceButton::SetCanFocus(bool canFocus) { this->canFocus = canFocus; }
void DeviceButton::SetIsSimpleMode(bool isSimpleMode)
{
m_isSimpleMode = isSimpleMode;
if ((this->active_icon.bmp().IsOk())) {
if (m_isSimpleMode) {
SetIconWithSize(this->active_icon.name(), wxSize(30, 30));
} else {
SetIconWithSize(this->active_icon.name(), wxSize(80, 80));
}
} else {
messureSize();
Refresh();
}
}
void DeviceButton::SetIsSelected(bool isSelected)
{
m_isSelected = isSelected;
if (m_isSelected) {
StateColor calc_btn_bg(std::pair<wxColour, int>(wxColour(26, 26, 28), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(26, 26, 28), StateColor::Hovered),
std::pair<wxColour, int>(wxColour(26, 26, 28), StateColor::Normal));
SetBackgroundColor(calc_btn_bg);
} else {
StateColor calc_btn_bg(std::pair<wxColour, int>(wxColour(26, 26, 28), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(26, 26, 28), StateColor::Hovered),
std::pair<wxColour, int>(wxColour(38, 38, 41), StateColor::Normal));
SetBackgroundColor(calc_btn_bg);
}
Refresh();
}
void DeviceButton::SetStateText(const wxString &text)
{
m_state_text = text;
Refresh();
}
void DeviceButton::SetProgressText(const wxString &text)
{
m_progress_text = text;
Refresh();
}
void DeviceButton::SetNameText(const wxString &text)
{
m_name_text = text;
Refresh();
}
void DeviceButton::SetIPText(const wxString &text)
{
m_ip_text = text;
Refresh();
}
void DeviceButton::Rescale()
{
/* if (this->active_icon.bmp().IsOk())
this->active_icon.msw_rescale();
if (this->inactive_icon.bmp().IsOk())
this->inactive_icon.msw_rescale();
*/
messureSize();
}
void DeviceButton::paintEvent(wxPaintEvent &evt)
{
// depending on your system you may need to look at double-buffered dcs
wxPaintDC dc(this);
render(dc);
}
/*
* Here we do the actual rendering. I put it in a separate
* method so that it can work no matter what type of DC
* (e.g. wxPaintDC or wxClientDC) is used.
*/
void DeviceButton::render(wxDC &dc)
{
StaticBox::render(dc);
int states = state_handler.states();
wxSize size = GetSize();
dc.SetBrush(*wxTRANSPARENT_BRUSH);
wxSize szIcon;
wxSize szContent = textSize;
ScalableBitmap icon;
if (m_selected || ((states & (int)StateColor::State::Hovered) != 0))
icon = active_icon;
else
icon = inactive_icon;
wxRect rcContent = {{0, 0}, size};
wxSize offset = (size - szContent) / 2;
if (offset.x < 0)
offset.x = 0;
rcContent.Deflate(offset.x, offset.y);
// y1
std::string tempName_string = m_name_text.ToStdString();
wxString m_name_text = wxString::FromUTF8(tempName_string);
if (GetLabel() == "") {
dc.DrawBitmap(icon.get_bitmap(), rcContent.x/2+1, rcContent.y/2);
} else if (m_ip_text == "") {
//dc.DrawBitmap(icon.get_bitmap(), 10, (GetSize().GetHeight() - icon.get_bitmap().GetHeight()) / 2);
if (m_isSimpleMode) {
dc.SetFont(wxFont(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD));
} else {
dc.SetFont(wxFont(12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD));
}
dc.SetTextForeground(text_color.colorForStates(states));
dc.DrawText(GetLabel(), rcContent.x / 2, size.y/2 - dc.GetTextExtent(GetLabel()).y / 2);
}
else if (m_isSimpleMode) {
dc.SetFont(wxFont(15, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD));
dc.SetTextForeground(wxColour(230, 230, 230));
dc.DrawText(m_name_text, 10, rcContent.y);
int dotRadius = 4;
int dotX = size.x - dotRadius - 10;
int dotY = 10;
if (m_isSelected) {
dc.SetBrush(wxBrush(wxColour(68, 121, 251)));
dc.SetPen(wxPen(wxColour(68, 121, 251)));
} else {
dc.SetBrush(wxBrush(wxColour(26, 26, 28)));
dc.SetPen(wxPen(wxColour(26, 26, 28)));
}
dc.DrawCircle(dotX, dotY, dotRadius);
} else {
dc.DrawBitmap(icon.get_bitmap(), 10, (GetSize().GetHeight() - icon.get_bitmap().GetHeight()) / 2);
dc.SetFont(wxFont(15, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD));
dc.SetTextForeground(wxColour(230, 230, 230));
dc.DrawText(m_name_text, 10 + icon.get_bitmap().GetWidth() + 10, rcContent.y-30);
dc.SetFont(wxFont(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD));
dc.SetTextForeground(wxColour(174, 174, 174));
dc.DrawText("IP:" + m_ip_text, 10 + icon.get_bitmap().GetWidth() + 10, rcContent.y);
wxBitmap m_bitmap_state = get_bmp_bundle("printer_state", 20)->GetBitmapFor(this);
dc.DrawBitmap(m_bitmap_state, 10 + icon.get_bitmap().GetWidth() + 10, rcContent.y + m_bitmap_state.GetWidth(), true);
dc.SetFont(wxFont(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD));
dc.SetTextForeground(wxColour(174, 174, 174));
dc.DrawText(m_state_text, 10 + icon.get_bitmap().GetWidth() + m_bitmap_state.GetWidth() + 15,
rcContent.y + m_bitmap_state.GetWidth() + (m_bitmap_state.GetWidth() - dc.GetTextExtent(m_state_text).y) / 2);
if (m_state_text == "printing") {
dc.SetFont(wxFont(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD));
dc.SetTextForeground(wxColour(33, 148, 239));
dc.DrawText(m_progress_text, 10 + icon.get_bitmap().GetWidth() + m_bitmap_state.GetWidth() + 77,
rcContent.y + m_bitmap_state.GetWidth() + (m_bitmap_state.GetWidth() - dc.GetTextExtent(m_progress_text).y) / 2+2);
}
int dotRadius = 4;
int dotX = size.x - dotRadius - 10;
int dotY = 10;
if (m_isSelected) {
dc.SetBrush(wxBrush(wxColour(68, 121, 251)));
dc.SetPen(wxPen(wxColour(68, 121, 251)));
} else {
dc.SetBrush(wxBrush(wxColour(26, 26, 28)));
dc.SetPen(wxPen(wxColour(26, 26, 28)));
}
dc.DrawCircle(dotX, dotY, dotRadius);
}
}
void DeviceButton::messureSize()
{
wxClientDC dc(this);
textSize = dc.GetTextExtent(GetLabel());
if (minSize.GetWidth() > 0) {
wxWindow::SetMinSize(minSize);
return;
}
wxSize szContent = textSize;
if (this->active_icon.bmp().IsOk()) {
if (szContent.y > 0) {
//BBS norrow size between text and icon
szContent.x += 5;
}
wxSize szIcon = this->active_icon.GetSize();
szContent.x += szIcon.x;
if (szIcon.y > szContent.y)
szContent.y = szIcon.y;
}
wxSize size = szContent + paddingSize * 2;
if (m_isSimpleMode && m_ip_text != "")
size.x = 180;
else if (m_ip_text != "")
size.x = 290;
if (minSize.GetHeight() > 0)
size.SetHeight(minSize.GetHeight());
wxWindow::SetMinSize(size);
}
void DeviceButton::mouseDown(wxMouseEvent &event)
{
event.Skip();
pressedDown = true;
if (canFocus)
SetFocus();
CaptureMouse();
}
void DeviceButton::mouseReleased(wxMouseEvent &event)
{
event.Skip();
if (pressedDown) {
pressedDown = false;
if (HasCapture())
ReleaseMouse();
if (wxRect({0, 0}, GetSize()).Contains(event.GetPosition()))
sendButtonEvent();
}
}
void DeviceButton::mouseCaptureLost(wxMouseCaptureLostEvent &event)
{
wxMouseEvent evt;
mouseReleased(evt);
}
void DeviceButton::keyDownUp(wxKeyEvent &event)
{
if (event.GetKeyCode() == WXK_SPACE || event.GetKeyCode() == WXK_RETURN) {
wxMouseEvent evt(event.GetEventType() == wxEVT_KEY_UP ? wxEVT_LEFT_UP : wxEVT_LEFT_DOWN);
event.SetEventObject(this);
GetEventHandler()->ProcessEvent(evt);
return;
}
if (event.GetEventType() == wxEVT_KEY_DOWN &&
(event.GetKeyCode() == WXK_TAB || event.GetKeyCode() == WXK_LEFT || event.GetKeyCode() == WXK_RIGHT
|| event.GetKeyCode() == WXK_UP || event.GetKeyCode() == WXK_DOWN))
HandleAsNavigationKey(event);
else
event.Skip();
}
void DeviceButton::sendButtonEvent()
{
wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, GetId());
event.SetEventObject(this);
GetEventHandler()->ProcessEvent(event);
}
#ifdef __WIN32__
WXLRESULT DeviceButton::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
{
if (nMsg == WM_GETDLGCODE) { return DLGC_WANTMESSAGE; }
if (nMsg == WM_KEYDOWN) {
wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_DOWN, wParam, lParam));
switch (wParam) {
case WXK_RETURN: { // WXK_RETURN key is handled by default button
GetEventHandler()->ProcessEvent(event);
return 0;
}
}
}
return wxWindow::MSWWindowProc(nMsg, wParam, lParam);
}
#endif
bool DeviceButton::AcceptsFocus() const { return canFocus; }

View File

@@ -0,0 +1,112 @@
#ifndef slic3r_GUI_DeviceButton2_hpp_
#define slic3r_GUI_DeviceButton2_hpp_
#include "../wxExtensions.hpp"
#include "StaticBox.hpp"
class DeviceButton : public StaticBox
{
wxSize textSize;
wxSize minSize; // set by outer
wxSize paddingSize;
ScalableBitmap active_icon;
ScalableBitmap inactive_icon;
StateColor text_color;
bool pressedDown = false;
bool m_selected = true;
bool canFocus = true;
static const int buttonWidth = 200;
static const int buttonHeight = 50;
public:
DeviceButton(wxString name_text, wxString ip_text);
DeviceButton(wxWindow *parent,
wxString text,
wxString icon = "",
long style = 0,
wxSize iconSize = wxSize(16, 16),
wxString name_text = "",
wxString ip_text = "");
bool Create(wxWindow* parent, wxString text, wxString icon = "", long style = 0, wxSize iconSize = wxSize(16, 16));
void SetLabel(const wxString& label) override;
void SetIconWithSize(const wxString &icon, wxSize iconSize);
void SetIcon(const wxString &icon);
void SetInactiveIcon(const wxString& icon);
void SetMinSize(const wxSize& size) override;
void SetPaddingSize(const wxSize& size);
void SetTextColor(StateColor const &color);
void SetTextColorNormal(wxColor const &color);
void SetSelected(bool selected = true) { m_selected = selected; }
bool Enable(bool enable = true) override;
void SetCanFocus(bool canFocus) override;
void SetIsSimpleMode(bool isSimpleMode);
void SetIsSelected(bool isSelected);
void SetStateText(const wxString &text);
void SetProgressText(const wxString &text);
void SetNameText(const wxString &text);
void SetIPText(const wxString &text);
bool GetIsSelected() { return m_isSelected; }
wxString getIPLabel() { return m_ip_text; };
wxString GetStateText() { return m_state_text; }
void Rescale();
protected:
#ifdef __WIN32__
WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) override;
#endif
bool AcceptsFocus() const override;
private:
void paintEvent(wxPaintEvent& evt);
void render(wxDC& dc);
void messureSize();
// some useful events
void mouseDown(wxMouseEvent& event);
void mouseReleased(wxMouseEvent& event);
void mouseCaptureLost(wxMouseCaptureLostEvent &event);
void keyDownUp(wxKeyEvent &event);
void sendButtonEvent();
wxString m_name_text;
wxString m_ip_text;
wxString m_state_text = "standby";
wxString m_progress_text = "(0%)";
bool m_isSimpleMode = true;
bool m_isSelected = false;
DECLARE_EVENT_TABLE()
};
#endif // !slic3r_GUI_Button_hpp_

View File

@@ -7,17 +7,19 @@
#include <wx/dcmemory.h>
#include <wx/dcclient.h>
//B64
SwitchButton::SwitchButton(wxWindow* parent, const wxString& name, wxWindowID id)
: BitmapToggleButton(parent, name, id)
, m_on(this, "toggle_on", 28, 16)
, m_off(this, "toggle_off", 28, 16)
, text_color(std::pair{*wxWHITE, (int) StateColor::Checked}, std::pair{0x6B6B6B, (int) StateColor::Normal})
, track_color(0xD9D9D9)
, thumb_color(std::pair{0x00AE42, (int) StateColor::Checked}, std::pair{0xD9D9D9, (int) StateColor::Normal})
, m_off(this, "toggle_off", 28, 16)
, text_color(std::pair{ 0x4479FB, (int) StateColor::Checked}, std::pair{0x6B6B6B, (int) StateColor::Normal})
, track_color(0x333337)
, thumb_color(std::pair{0x4479FB, (int) StateColor::Checked}, std::pair{0x333337, (int) StateColor::Normal})
{
Rescale();
}
void SwitchButton::SetLabels(wxString const& lbl_on, wxString const& lbl_off)
{
labels[0] = lbl_on;
@@ -47,6 +49,14 @@ void SwitchButton::SetValue(bool value)
update();
}
void SwitchButton::SetSize(int size)
{
m_size = size;
update();
Rescale();
}
//B64
void SwitchButton::Rescale()
{
if (!labels[0].IsEmpty()) {
@@ -72,10 +82,13 @@ void SwitchButton::Rescale()
auto size = textSize[1];
if (size.x > thumbSize.x) thumbSize.x = size.x;
else size.x = thumbSize.x;
thumbSize.x += BS * 12;
thumbSize.y += BS * 6;
trackSize.x = thumbSize.x + size.x + BS * 10;
trackSize.y = thumbSize.y + BS * 2;
//thumbSize.x += BS * 12 *10;
//thumbSize.y += BS * 6;
thumbSize.x = m_size/2;
thumbSize.y = 25;
trackSize.x = m_size;
trackSize.y = 30;
auto maxWidth = GetMaxWidth();
#ifdef __WXOSX__
maxWidth *= scale;
@@ -91,7 +104,8 @@ void SwitchButton::Rescale()
memdc.SelectObject(bmp);
memdc.SetBackground(wxBrush(GetBackgroundColour()));
memdc.Clear();
memdc.SetFont(dc.GetFont());
//memdc.SetFont(dc.GetFont());
memdc.SetFont(wxFont(12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD));
auto state = i == 0 ? StateColor::Enabled : (StateColor::Checked | StateColor::Enabled);
{
#ifdef __WXMSW__
@@ -101,15 +115,30 @@ void SwitchButton::Rescale()
#endif
dc2.SetBrush(wxBrush(track_color.colorForStates(state)));
dc2.SetPen(wxPen(track_color.colorForStates(state)));
dc2.DrawRoundedRectangle(wxRect({0, 0}, trackSize), trackSize.y / 2);
dc2.SetBrush(wxBrush(thumb_color.colorForStates(StateColor::Checked | StateColor::Enabled)));
dc2.DrawRectangle(wxRect({0, 0}, trackSize));
dc2.SetBrush(wxBrush(track_color.colorForStates(state)));
dc2.SetPen(wxPen(track_color.colorForStates(state)));
dc2.DrawRectangle(wxRect({i == 0 ? BS : (trackSize.x - thumbSize.x - BS), BS}, thumbSize));
dc2.SetPen(wxPen(thumb_color.colorForStates(StateColor::Checked | StateColor::Enabled)));
dc2.DrawRoundedRectangle(wxRect({ i == 0 ? BS : (trackSize.x - thumbSize.x - BS), BS}, thumbSize), thumbSize.y / 2);
//dc2.DrawLine(i == 0 ? 2 * BS + (thumbSize.x - textSize[0].x) / 2 :
// trackSize.x - thumbSize.x + (thumbSize.x - textSize[1].x) / 2,
// thumbSize.y, i == 0 ? thumbSize.x / 2 + textSize[0].x : trackSize.x - thumbSize.x / 2 - 2 * BS + textSize[1].x,
// thumbSize.y);
}
memdc.SetTextForeground(text_color.colorForStates(state ^ StateColor::Checked));
memdc.DrawText(labels[0], {BS + (thumbSize.x - textSize[0].x) / 2, BS + (thumbSize.y - textSize[0].y) / 2});
memdc.SetTextForeground(text_color.colorForStates(state));
memdc.DrawText(labels[1], {trackSize.x - thumbSize.x - BS + (thumbSize.x - textSize[1].x) / 2, BS + (thumbSize.y - textSize[1].y) / 2});
//memdc.SetPen(wxPen(wxColour(68, 121, 251)));
// if (!GetValue())
// memdc.DrawLine(BS + BS * 10 * 7, thumbSize.y, BS + BS * 10 * 10, thumbSize.y);
// else
// memdc.DrawLine(trackSize.x - thumbSize.x + BS * 10 * 7 - BS * 4, thumbSize.y,
// trackSize.x - thumbSize.x + BS * 10 * 10 - BS * 4, thumbSize.y);
memdc.SelectObject(wxNullBitmap);
#ifdef __WXOSX__
bmp = wxBitmap(bmp.ConvertToImage(), -1, scale);

View File

@@ -9,6 +9,7 @@
class SwitchButton : public BitmapToggleButton
{
public:
//B64
SwitchButton(wxWindow * parent = NULL, const wxString& name = wxEmptyString, wxWindowID id = wxID_ANY);
public:
@@ -26,12 +27,18 @@ public:
void SysColorChange();
//B64
void SetSize(int size);
private:
void update() override;
private:
ScalableBitmap m_on;
ScalableBitmap m_off;
//B64
int m_size = 300;
wxString labels[2];
StateColor text_color;