NEW: warning before user move e axis
Change-Id: Ic06d0fa3b5ff19608a53e2d276d91375156bdc82
This commit is contained in:
parent
5338247639
commit
536df6ca23
|
@ -24,6 +24,7 @@
|
||||||
namespace Slic3r { namespace GUI {
|
namespace Slic3r { namespace GUI {
|
||||||
|
|
||||||
wxDEFINE_EVENT(EVT_SECONDARY_CHECK_CONFIRM, wxCommandEvent);
|
wxDEFINE_EVENT(EVT_SECONDARY_CHECK_CONFIRM, wxCommandEvent);
|
||||||
|
wxDEFINE_EVENT(EVT_SECONDARY_CHECK_CANCEL, wxCommandEvent);
|
||||||
|
|
||||||
ReleaseNoteDialog::ReleaseNoteDialog(Plater *plater /*= nullptr*/)
|
ReleaseNoteDialog::ReleaseNoteDialog(Plater *plater /*= nullptr*/)
|
||||||
: DPIDialog(static_cast<wxWindow *>(wxGetApp().mainframe), wxID_ANY, _L("Release Note"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
|
: DPIDialog(static_cast<wxWindow *>(wxGetApp().mainframe), wxID_ANY, _L("Release Note"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
|
||||||
|
@ -342,7 +343,7 @@ void UpdateVersionDialog::update_version_info(wxString release_note, wxString ve
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SecondaryCheckDialog::SecondaryCheckDialog(wxWindow* parent, wxWindowID id, const wxString& title, enum ButtonStyle btn_style, const wxPoint& pos, const wxSize& size, long style)
|
SecondaryCheckDialog::SecondaryCheckDialog(wxWindow* parent, wxWindowID id, const wxString& title, enum ButtonStyle btn_style, const wxPoint& pos, const wxSize& size, long style, bool not_show_again_check)
|
||||||
:DPIFrame(parent, id, title, pos, size, style)
|
:DPIFrame(parent, id, title, pos, size, style)
|
||||||
{
|
{
|
||||||
std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
|
std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
|
||||||
|
@ -363,8 +364,10 @@ SecondaryCheckDialog::SecondaryCheckDialog(wxWindow* parent, wxWindowID id, cons
|
||||||
m_vebview_release_note->SetScrollRate(0, 5);
|
m_vebview_release_note->SetScrollRate(0, 5);
|
||||||
m_vebview_release_note->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
|
m_vebview_release_note->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
|
||||||
m_vebview_release_note->SetMinSize(wxSize(FromDIP(280), FromDIP(280)));
|
m_vebview_release_note->SetMinSize(wxSize(FromDIP(280), FromDIP(280)));
|
||||||
|
m_sizer_right->Add(m_vebview_release_note, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(35));
|
||||||
|
|
||||||
|
|
||||||
|
auto bottom_sizer = new wxBoxSizer(wxVERTICAL);
|
||||||
auto sizer_button = new wxBoxSizer(wxHORIZONTAL);
|
auto sizer_button = new wxBoxSizer(wxHORIZONTAL);
|
||||||
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));
|
||||||
|
@ -372,20 +375,29 @@ SecondaryCheckDialog::SecondaryCheckDialog(wxWindow* parent, wxWindowID id, cons
|
||||||
StateColor btn_bg_white(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed), std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Hovered),
|
StateColor btn_bg_white(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed), std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Hovered),
|
||||||
std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
|
std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
|
||||||
|
|
||||||
|
|
||||||
|
if (not_show_again_check) {
|
||||||
|
m_show_again_checkbox = new wxCheckBox(this, wxID_ANY, _L("Don't show again"), wxDefaultPosition, wxDefaultSize, 0);
|
||||||
|
m_show_again_checkbox->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, [this](wxCommandEvent& e) {
|
||||||
|
not_show_again = !not_show_again;
|
||||||
|
m_show_again_checkbox->SetValue(not_show_again);
|
||||||
|
});
|
||||||
|
bottom_sizer->Add(m_show_again_checkbox, 0, wxALL, FromDIP(5));
|
||||||
|
}
|
||||||
m_button_ok = new Button(this, _L("Confirm"));
|
m_button_ok = new Button(this, _L("Confirm"));
|
||||||
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(*wxWHITE);
|
m_button_ok->SetTextColor(*wxWHITE);
|
||||||
m_button_ok->SetFont(Label::Body_12);
|
m_button_ok->SetFont(Label::Body_12);
|
||||||
m_button_ok->SetSize(wxSize(FromDIP(58), FromDIP(24)));
|
m_button_ok->SetSize(wxSize(FromDIP(58), FromDIP(24)));
|
||||||
m_button_ok->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
|
m_button_ok->SetMinSize(wxSize(-1, FromDIP(24)));
|
||||||
m_button_ok->SetCornerRadius(FromDIP(12));
|
m_button_ok->SetCornerRadius(FromDIP(12));
|
||||||
|
|
||||||
m_button_ok->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& e) {
|
m_button_ok->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& e) {
|
||||||
wxCommandEvent evt(EVT_SECONDARY_CHECK_CONFIRM, GetId());
|
wxCommandEvent evt(EVT_SECONDARY_CHECK_CONFIRM, GetId());
|
||||||
e.SetEventObject(this);
|
e.SetEventObject(this);
|
||||||
GetEventHandler()->ProcessEvent(evt);
|
GetEventHandler()->ProcessEvent(evt);
|
||||||
this->Hide();
|
this->on_hide();
|
||||||
});
|
});
|
||||||
|
|
||||||
m_button_cancel = new Button(this, _L("Cancel"));
|
m_button_cancel = new Button(this, _L("Cancel"));
|
||||||
|
@ -393,11 +405,14 @@ SecondaryCheckDialog::SecondaryCheckDialog(wxWindow* parent, wxWindowID id, cons
|
||||||
m_button_cancel->SetBorderColor(wxColour(38, 46, 48));
|
m_button_cancel->SetBorderColor(wxColour(38, 46, 48));
|
||||||
m_button_cancel->SetFont(Label::Body_12);
|
m_button_cancel->SetFont(Label::Body_12);
|
||||||
m_button_cancel->SetSize(wxSize(FromDIP(58), FromDIP(24)));
|
m_button_cancel->SetSize(wxSize(FromDIP(58), FromDIP(24)));
|
||||||
m_button_cancel->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
|
m_button_cancel->SetMinSize(wxSize(-1, FromDIP(24)));
|
||||||
m_button_cancel->SetCornerRadius(FromDIP(12));
|
m_button_cancel->SetCornerRadius(FromDIP(12));
|
||||||
|
|
||||||
m_button_cancel->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& e) {
|
m_button_cancel->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& e) {
|
||||||
this->Hide();
|
wxCommandEvent evt(EVT_SECONDARY_CHECK_CANCEL);
|
||||||
|
e.SetEventObject(this);
|
||||||
|
GetEventHandler()->ProcessEvent(evt);
|
||||||
|
this->on_hide();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (btn_style != CONFIRM_AND_CANCEL)
|
if (btn_style != CONFIRM_AND_CANCEL)
|
||||||
|
@ -408,13 +423,13 @@ SecondaryCheckDialog::SecondaryCheckDialog(wxWindow* parent, wxWindowID id, cons
|
||||||
sizer_button->AddStretchSpacer();
|
sizer_button->AddStretchSpacer();
|
||||||
sizer_button->Add(m_button_ok, 0, wxALL, FromDIP(5));
|
sizer_button->Add(m_button_ok, 0, wxALL, FromDIP(5));
|
||||||
sizer_button->Add(m_button_cancel, 0, wxALL, FromDIP(5));
|
sizer_button->Add(m_button_cancel, 0, wxALL, FromDIP(5));
|
||||||
|
bottom_sizer->Add(sizer_button, 0, wxEXPAND | wxRIGHT | wxLEFT, 0);
|
||||||
|
|
||||||
|
|
||||||
m_sizer_right->Add(m_vebview_release_note, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(35));
|
m_sizer_right->Add(bottom_sizer, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(35));
|
||||||
m_sizer_right->Add(sizer_button, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(35));
|
|
||||||
m_sizer_right->Add(0, 0, 0, wxTOP,FromDIP(18));
|
m_sizer_right->Add(0, 0, 0, wxTOP,FromDIP(18));
|
||||||
|
|
||||||
Bind(wxEVT_CLOSE_WINDOW, [this](auto& e) {this->Hide();});
|
Bind(wxEVT_CLOSE_WINDOW, [this](auto& e) {this->on_hide();});
|
||||||
|
|
||||||
SetSizer(m_sizer_right);
|
SetSizer(m_sizer_right);
|
||||||
Layout();
|
Layout();
|
||||||
|
@ -464,50 +479,19 @@ void SecondaryCheckDialog::on_show()
|
||||||
this->SetFocus();
|
this->SetFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SecondaryCheckDialog::is_english_text(wxString str)
|
void SecondaryCheckDialog::on_hide()
|
||||||
{
|
{
|
||||||
std::regex reg("^[0-9a-zA-Z]+$");
|
if (m_show_again_checkbox != nullptr && not_show_again && show_again_config_text != "")
|
||||||
std::smatch matchResult;
|
wxGetApp().app_config->set(show_again_config_text, "1");
|
||||||
|
|
||||||
std::string pattern_Special = "{}[]<>~!@#$%^&*(),.?/ :";
|
this->Hide();
|
||||||
for (auto i = 0; i < str.Length(); i++) {
|
|
||||||
std::string regex_str = wxString(str[i]).ToStdString();
|
|
||||||
if(std::regex_match(regex_str, matchResult, reg)){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int result = pattern_Special.find(regex_str.c_str());
|
|
||||||
if (result < 0 || result > pattern_Special.length()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString SecondaryCheckDialog::format_text(wxStaticText* st, wxString str, int warp)
|
void SecondaryCheckDialog::update_btn_label(wxString ok_btn_text, wxString cancel_btn_text)
|
||||||
{
|
{
|
||||||
if (wxGetApp().app_config->get("language") != "zh_CN") { return str; }
|
m_button_ok->SetLabel(ok_btn_text);
|
||||||
|
m_button_cancel->SetLabel(cancel_btn_text);
|
||||||
wxString out_txt = str;
|
rescale();
|
||||||
wxString count_txt = "";
|
|
||||||
int new_line_pos = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < str.length(); i++) {
|
|
||||||
if (str[i] == '\n') {
|
|
||||||
count_txt = "";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
auto text_size = st->GetTextExtent(count_txt);
|
|
||||||
if (text_size.x < warp) {
|
|
||||||
count_txt += str[i];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
out_txt.insert(i - 1, '\n');
|
|
||||||
count_txt = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return out_txt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SecondaryCheckDialog::~SecondaryCheckDialog()
|
SecondaryCheckDialog::~SecondaryCheckDialog()
|
||||||
|
@ -516,6 +500,11 @@ SecondaryCheckDialog::~SecondaryCheckDialog()
|
||||||
}
|
}
|
||||||
|
|
||||||
void SecondaryCheckDialog::on_dpi_changed(const wxRect& suggested_rect)
|
void SecondaryCheckDialog::on_dpi_changed(const wxRect& suggested_rect)
|
||||||
|
{
|
||||||
|
rescale();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SecondaryCheckDialog::rescale()
|
||||||
{
|
{
|
||||||
m_button_ok->Rescale();
|
m_button_ok->Rescale();
|
||||||
m_button_cancel->Rescale();
|
m_button_cancel->Rescale();
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
namespace Slic3r { namespace GUI {
|
namespace Slic3r { namespace GUI {
|
||||||
|
|
||||||
wxDECLARE_EVENT(EVT_SECONDARY_CHECK_CONFIRM, wxCommandEvent);
|
wxDECLARE_EVENT(EVT_SECONDARY_CHECK_CONFIRM, wxCommandEvent);
|
||||||
|
wxDECLARE_EVENT(EVT_SECONDARY_CHECK_CANCEL, wxCommandEvent);
|
||||||
|
|
||||||
class ReleaseNoteDialog : public DPIDialog
|
class ReleaseNoteDialog : public DPIDialog
|
||||||
{
|
{
|
||||||
|
@ -95,12 +96,14 @@ public:
|
||||||
enum ButtonStyle btn_style = CONFIRM_AND_CANCEL,
|
enum ButtonStyle btn_style = CONFIRM_AND_CANCEL,
|
||||||
const wxPoint& pos = wxDefaultPosition,
|
const wxPoint& pos = wxDefaultPosition,
|
||||||
const wxSize& size = wxDefaultSize,
|
const wxSize& size = wxDefaultSize,
|
||||||
long style = wxCLOSE_BOX | wxCAPTION
|
long style = wxCLOSE_BOX | wxCAPTION,
|
||||||
|
bool not_show_again_check = false
|
||||||
);
|
);
|
||||||
void update_text(wxString text);
|
void update_text(wxString text);
|
||||||
void on_show();
|
void on_show();
|
||||||
bool is_english_text(wxString str);
|
void on_hide();
|
||||||
wxString format_text(wxStaticText* st, wxString str, int warp);
|
void update_btn_label(wxString ok_btn_text, wxString cancel_btn_text);
|
||||||
|
void rescale();
|
||||||
~SecondaryCheckDialog();
|
~SecondaryCheckDialog();
|
||||||
void on_dpi_changed(const wxRect& suggested_rect);
|
void on_dpi_changed(const wxRect& suggested_rect);
|
||||||
|
|
||||||
|
@ -108,6 +111,9 @@ public:
|
||||||
wxScrolledWindow *m_vebview_release_note {nullptr};
|
wxScrolledWindow *m_vebview_release_note {nullptr};
|
||||||
Button* m_button_ok;
|
Button* m_button_ok;
|
||||||
Button* m_button_cancel;
|
Button* m_button_cancel;
|
||||||
|
wxCheckBox* m_show_again_checkbox;
|
||||||
|
bool not_show_again = false;
|
||||||
|
std::string show_again_config_text = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
}} // namespace Slic3r::GUI
|
}} // namespace Slic3r::GUI
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
namespace Slic3r { namespace GUI {
|
namespace Slic3r { namespace GUI {
|
||||||
|
|
||||||
#define TEMP_THRESHOLD_VAL 2
|
#define TEMP_THRESHOLD_VAL 2
|
||||||
|
#define TEMP_THRESHOLD_ALLOW_E_CTRL 170.0f
|
||||||
|
|
||||||
/* const strings */
|
/* const strings */
|
||||||
static const wxString NA_STR = _L("N/A");
|
static const wxString NA_STR = _L("N/A");
|
||||||
|
@ -1198,6 +1199,9 @@ StatusPanel::~StatusPanel()
|
||||||
if (abort_dlg != nullptr)
|
if (abort_dlg != nullptr)
|
||||||
delete abort_dlg;
|
delete abort_dlg;
|
||||||
|
|
||||||
|
if (ctrl_e_hint_dlg != nullptr)
|
||||||
|
delete ctrl_e_hint_dlg;
|
||||||
|
|
||||||
if (sdcard_hint_dlg != nullptr)
|
if (sdcard_hint_dlg != nullptr)
|
||||||
delete sdcard_hint_dlg;
|
delete sdcard_hint_dlg;
|
||||||
}
|
}
|
||||||
|
@ -1437,7 +1441,7 @@ void StatusPanel::show_error_message(wxString msg)
|
||||||
}
|
}
|
||||||
if (m_print_error_dlg != nullptr) {
|
if (m_print_error_dlg != nullptr) {
|
||||||
if (m_print_error_dlg->IsShown()) {
|
if (m_print_error_dlg->IsShown()) {
|
||||||
m_print_error_dlg->Hide();
|
m_print_error_dlg->on_hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2158,14 +2162,46 @@ void StatusPanel::on_axis_ctrl_z_down_10(wxCommandEvent &event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StatusPanel::axis_ctrl_e_hint(bool up_down)
|
||||||
|
{
|
||||||
|
if (ctrl_e_hint_dlg == nullptr) {
|
||||||
|
ctrl_e_hint_dlg = new SecondaryCheckDialog(this->GetParent(), wxID_ANY, _L("Warning"), SecondaryCheckDialog::ButtonStyle::CONFIRM_AND_CANCEL, wxDefaultPosition, wxDefaultSize, wxCLOSE_BOX | wxCAPTION, true);
|
||||||
|
ctrl_e_hint_dlg->update_text(_L("Please heat the nozzle to above 170 degree before loading filament."));
|
||||||
|
ctrl_e_hint_dlg->show_again_config_text = std::string("not_show_ectrl_hint");
|
||||||
|
}
|
||||||
|
if (up_down) {
|
||||||
|
ctrl_e_hint_dlg->update_btn_label(_L("Confirm"), _L("Still unload"));
|
||||||
|
ctrl_e_hint_dlg->Bind(EVT_SECONDARY_CHECK_CANCEL, [this](wxCommandEvent& e) {
|
||||||
|
obj->command_axis_control("E", 1.0, -10.0f, 900);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctrl_e_hint_dlg->update_btn_label(_L("Confirm"), _L("Still load"));
|
||||||
|
ctrl_e_hint_dlg->Bind(EVT_SECONDARY_CHECK_CANCEL, [this](wxCommandEvent& e) {
|
||||||
|
obj->command_axis_control("E", 1.0, 10.0f, 900);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
ctrl_e_hint_dlg->on_show();
|
||||||
|
}
|
||||||
|
|
||||||
void StatusPanel::on_axis_ctrl_e_up_10(wxCommandEvent &event)
|
void StatusPanel::on_axis_ctrl_e_up_10(wxCommandEvent &event)
|
||||||
{
|
{
|
||||||
if (obj) obj->command_axis_control("E", 1.0, -10.0f, 900);
|
if (obj) {
|
||||||
|
if (obj->nozzle_temp >= TEMP_THRESHOLD_ALLOW_E_CTRL || (wxGetApp().app_config->get("not_show_ectrl_hint") == "1"))
|
||||||
|
obj->command_axis_control("E", 1.0, -10.0f, 900);
|
||||||
|
else
|
||||||
|
axis_ctrl_e_hint(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatusPanel::on_axis_ctrl_e_down_10(wxCommandEvent &event)
|
void StatusPanel::on_axis_ctrl_e_down_10(wxCommandEvent &event)
|
||||||
{
|
{
|
||||||
if (obj) obj->command_axis_control("E", 1.0, 10.0f, 900);
|
if (obj) {
|
||||||
|
if (obj->nozzle_temp >= TEMP_THRESHOLD_ALLOW_E_CTRL || (wxGetApp().app_config->get("not_show_ectrl_hint") == "1"))
|
||||||
|
obj->command_axis_control("E", 1.0, 10.0f, 900);
|
||||||
|
else
|
||||||
|
axis_ctrl_e_hint(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatusPanel::on_start_unload(wxCommandEvent &event)
|
void StatusPanel::on_start_unload(wxCommandEvent &event)
|
||||||
|
|
|
@ -261,6 +261,7 @@ protected:
|
||||||
AMSMaterialsSetting *m_filament_setting_dlg{nullptr};
|
AMSMaterialsSetting *m_filament_setting_dlg{nullptr};
|
||||||
SecondaryCheckDialog* m_print_error_dlg = nullptr;
|
SecondaryCheckDialog* m_print_error_dlg = nullptr;
|
||||||
SecondaryCheckDialog* abort_dlg = nullptr;
|
SecondaryCheckDialog* abort_dlg = nullptr;
|
||||||
|
SecondaryCheckDialog* ctrl_e_hint_dlg = nullptr;
|
||||||
SecondaryCheckDialog* sdcard_hint_dlg = nullptr;
|
SecondaryCheckDialog* sdcard_hint_dlg = nullptr;
|
||||||
|
|
||||||
wxString m_request_url;
|
wxString m_request_url;
|
||||||
|
@ -299,6 +300,7 @@ protected:
|
||||||
void on_axis_ctrl_z_down_10(wxCommandEvent &event);
|
void on_axis_ctrl_z_down_10(wxCommandEvent &event);
|
||||||
void on_axis_ctrl_e_up_10(wxCommandEvent &event);
|
void on_axis_ctrl_e_up_10(wxCommandEvent &event);
|
||||||
void on_axis_ctrl_e_down_10(wxCommandEvent &event);
|
void on_axis_ctrl_e_down_10(wxCommandEvent &event);
|
||||||
|
void axis_ctrl_e_hint(bool up_down);
|
||||||
|
|
||||||
void on_start_unload(wxCommandEvent &event);
|
void on_start_unload(wxCommandEvent &event);
|
||||||
/* temp control */
|
/* temp control */
|
||||||
|
|
Loading…
Reference in New Issue