diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 9c60240de6..f4c842699d 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -2611,12 +2611,15 @@ void GUI_App::add_config_menu(wxMenuBar *menu) break; case ConfigMenuWifiConfigFile: { + open_wifi_config_dialog(); + /* std::string file_path; WifiConfigDialog dialog(mainframe, file_path, removable_drive_manager()); if (dialog.ShowModal() == wxID_OK) { plater_->get_notification_manager()->push_exporting_finished_notification(file_path, boost::filesystem::path(file_path).parent_path().string(), true); } + */ } break; default: @@ -3571,5 +3574,19 @@ void GUI_App::start_download(std::string url) m_downloader->start_download(url); } +void GUI_App::open_wifi_config_dialog(const wxString& drive_path/* = {}*/) +{ + if(m_wifi_config_dialog_shown) + return; + m_wifi_config_dialog_shown = true; + std::string file_path; + WifiConfigDialog dialog(mainframe, file_path, removable_drive_manager(), drive_path); + if (dialog.ShowModal() == wxID_OK) + { + plater_->get_notification_manager()->push_exporting_finished_notification(file_path, boost::filesystem::path(file_path).parent_path().string(), true); + } + m_wifi_config_dialog_shown = false; +} + } // GUI } //Slic3r diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 059804edf3..3d705bee9e 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -379,6 +379,8 @@ public: // URL download - PrusaSlicer gets system call to open prusaslicer:// URL which should contain address of download void start_download(std::string url); + void open_wifi_config_dialog(const wxString& drive_path = {}); + bool get_wifi_config_dialog_shown() const { return m_wifi_config_dialog_shown; } private: bool on_init_inner(); void init_app_config(); @@ -401,7 +403,7 @@ private: void app_version_check(bool from_user); bool m_datadir_redefined { false }; - + bool m_wifi_config_dialog_shown { false }; }; DECLARE_APP(GUI_App) diff --git a/src/slic3r/GUI/NotificationManager.hpp b/src/slic3r/GUI/NotificationManager.hpp index 458f1f5b08..d74b28af60 100644 --- a/src/slic3r/GUI/NotificationManager.hpp +++ b/src/slic3r/GUI/NotificationManager.hpp @@ -128,6 +128,8 @@ enum class NotificationType URLDownload, // MacOS specific - PS comes forward even when downloader is not allowed URLNotRegistered, + // Config file was detected during startup, open wifi config dialog via hypertext + WifiConfigFileDetected }; class NotificationManager diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 38f84004e2..4ee3493fc7 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2284,6 +2284,26 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) // Close notification ExportingFinished but only if last export was to removable notification_manager->device_ejected(); }); + + this->q->Bind(EVT_REMOVABLE_DRIVE_ADDED, [this](wxCommandEvent& evt) { + const std::string CONFIG_FILE_NAME = "prusa_printer_settings.ini"; + if (evt.GetInt() == 0) { // not at startup, show dialog + if (fs::exists(fs::path(evt.GetString().utf8_string()) / CONFIG_FILE_NAME)) + wxGetApp().open_wifi_config_dialog(evt.GetString()); + } else { // at startup, show only notification + notification_manager->push_notification(NotificationType::WifiConfigFileDetected + , NotificationManager::NotificationLevel::ImportantNotificationLevel + // TRN Text of notification when Slicer starts and usb stick with printer settings ini file is present + , _u8L("Printer configuration file detected on removable media.") + // TRN Text of hypertext of notification when Slicer starts and usb stick with printer settings ini file is present + , _u8L("Write Wi-Fi credetials."), [evt, CONFIG_FILE_NAME](wxEvtHandler* evt_hndlr){ + if (fs::exists(fs::path(evt.GetString().utf8_string()) / CONFIG_FILE_NAME)) + wxGetApp().open_wifi_config_dialog(evt.GetString()); + return true;}); + } + + }); + // Start the background thread and register this window as a target for update events. wxGetApp().removable_drive_manager()->init(this->q); #ifdef _WIN32 diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 4eeae25041..52ae1dad8b 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -44,6 +44,8 @@ namespace GUI { wxDEFINE_EVENT(EVT_REMOVABLE_DRIVE_EJECTED, RemovableDriveEjectEvent); wxDEFINE_EVENT(EVT_REMOVABLE_DRIVES_CHANGED, RemovableDrivesChangedEvent); +wxDEFINE_EVENT(EVT_REMOVABLE_DRIVE_ADDED, wxCommandEvent); + #if _WIN32 std::vector RemovableDriveManager::search_for_removable_drives() const @@ -1036,11 +1038,28 @@ void RemovableDriveManager::update() std::scoped_lock lock(m_drives_mutex); std::sort(current_drives.begin(), current_drives.end()); if (current_drives != m_current_drives) { + // event for writing / ejecting functions assert(m_callback_evt_handler); if (m_callback_evt_handler) wxPostEvent(m_callback_evt_handler, RemovableDrivesChangedEvent(EVT_REMOVABLE_DRIVES_CHANGED)); + + // event for printer config file + std::vector new_drives; + std::set_difference(current_drives.begin(), current_drives.end(), m_current_drives.begin(), m_current_drives.end(), + std::inserter(new_drives, new_drives.begin())); + + for (const DriveData& data : new_drives) { + if (data.path.empty()) + continue; + wxCommandEvent* evt = new wxCommandEvent(EVT_REMOVABLE_DRIVE_ADDED); + evt->SetString(boost::nowide::widen(data.path)); + evt->SetInt((int)m_first_update); + m_callback_evt_handler->QueueEvent(evt); + } + } m_current_drives = std::move(current_drives); + m_first_update = false; } else { // Acquiring the m_iniside_update lock failed, therefore another update is running. // Just block until the other instance of update() finishes. diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 14ea4d290e..f5674bdfef 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -42,6 +42,8 @@ wxDECLARE_EVENT(EVT_REMOVABLE_DRIVE_EJECTED, RemovableDriveEjectEvent); using RemovableDrivesChangedEvent = SimpleEvent; wxDECLARE_EVENT(EVT_REMOVABLE_DRIVES_CHANGED, RemovableDrivesChangedEvent); +wxDECLARE_EVENT(EVT_REMOVABLE_DRIVE_ADDED, wxCommandEvent); + #if __APPLE__ // Callbacks on device plug / unplug work reliably on OSX. #define REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS @@ -98,7 +100,7 @@ private: bool m_initialized { false }; wxEvtHandler* m_callback_evt_handler { nullptr }; - + bool m_first_update{ true }; #ifndef REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS // Worker thread, worker thread synchronization and callbacks to the UI thread. void thread_proc(); diff --git a/src/slic3r/GUI/WifiConfigDialog.cpp b/src/slic3r/GUI/WifiConfigDialog.cpp index 1f5c94db7b..8240da6f4f 100644 --- a/src/slic3r/GUI/WifiConfigDialog.cpp +++ b/src/slic3r/GUI/WifiConfigDialog.cpp @@ -10,8 +10,10 @@ #include #include #include +#include #include #include +#include #include "Widgets/ComboBox.hpp" @@ -20,15 +22,13 @@ namespace GUI { const char* WIFI_CONFIGFILE_NAME = "prusa_printer_settings.ini"; -WifiConfigDialog::WifiConfigDialog(wxWindow* parent, std::string& file_path, RemovableDriveManager* removable_manager) +WifiConfigDialog::WifiConfigDialog(wxWindow* parent, std::string& file_path, RemovableDriveManager* removable_manager, const wxString& preffered_drive) // TRN: This is the dialog title. : DPIDialog(parent, wxID_ANY, _L("Wi-Fi Configuration File Generator"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) , m_wifi_scanner(new WifiScanner()) , out_file_path(file_path) , m_removable_manager(removable_manager) { - const int em = GUI::wxGetApp().em_unit(); - wxPanel* panel = new wxPanel(this); wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL); panel->SetSizer(vsizer); @@ -73,7 +73,7 @@ WifiConfigDialog::WifiConfigDialog(wxWindow* parent, std::string& file_path, Rem // TRN description of Combo Box with path to USB drive. wxStaticText* drive_label = new wxStaticText(panel, wxID_ANY, GUI::format_wxstr("%1%:", _L("Drive"))); m_drive_combo = new ::ComboBox(panel, wxID_ANY); - rescan_drives(); + rescan_drives(preffered_drive); // TRN Text of button to rescan connect usb drives in Wifi Config dialog. wxButton* drive_button = new wxButton(panel, wxID_ANY, _(L("Rescan"))); drive_sizer->Add(m_drive_combo, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT, 10); @@ -156,18 +156,21 @@ void WifiConfigDialog::on_retrieve_password(wxCommandEvent& e) void WifiConfigDialog::on_rescan_drives(wxCommandEvent& e) { - rescan_drives(); + rescan_drives({}); } -void WifiConfigDialog::rescan_drives() +void WifiConfigDialog::rescan_drives(const wxString& preffered_drive) { assert(m_drive_combo && m_removable_manager); m_drive_combo->Clear(); std::vector ddata = m_removable_manager->get_drive_list(); for (const auto& data : ddata) { - m_drive_combo->Append(boost::nowide::widen(data.path)); + wxString item = boost::nowide::widen(data.path); + m_drive_combo->Append(item); + if (preffered_drive == item) + m_ssid_combo->Select(m_ssid_combo->GetCount() - 1); } - if (m_drive_combo->GetCount() > 0) { + if (m_drive_combo->GetSelection() == -1 && m_drive_combo->GetCount() > 0) { m_drive_combo->Select(0); } } @@ -225,6 +228,7 @@ void WifiConfigDialog::on_ok(wxCommandEvent& e) return; } +#if 0 // older variant of rewriting previous ini file if (boost::filesystem::exists(file_path)) { wxString msg_text = GUI::format_wxstr("%1% already exists. Do you want to rewrite it?", file_path.string()); @@ -234,16 +238,41 @@ void WifiConfigDialog::on_ok(wxCommandEvent& e) return; } } - - wxString ssid = m_ssid_combo->GetValue(); - wxString pass = m_pass_textctrl->GetValue(); - std::string data = GUI::format( - "[wifi]\n" - "ssid=%1%\n" - "psk=%2%\n" - , ssid - , pass - ); +#endif + + std::string data; + namespace pt = boost::property_tree; + pt::ptree tree; + // File already exist and we only need to add data to it rather than rewrite it. + if (boost::filesystem::exists(file_path)) { + + boost::nowide::ifstream ifs(file_path.string()); + try { + pt::read_ini(ifs, tree); + } + catch (const boost::property_tree::ini_parser::ini_parser_error& err) { + throw Slic3r::RuntimeError(format("Failed loading ini file \"%1%\"\nError: \"%2%\" at line %3%", file_path, err.message(), err.line()).c_str()); + } + + if (auto sub = tree.get_optional("wifi"); sub) { + tree.erase("wifi"); + } + } + + pt::ptree subtree; + subtree.put("ssid", m_ssid_combo->GetValue().utf8_string()); + subtree.put("psk", m_pass_textctrl->GetValue().utf8_string()); + tree.add_child("wifi", subtree); + + data.clear(); + // manually write ini string (so there is extra line between sections) + for (const auto& section : tree) { + data += "[" + section.first + "]" + "\n"; + for (const auto& entry : section.second) { + data += entry.first + " = " + entry.second.get_value() + "\n"; + } + data += "\n"; + } FILE* file; file = fopen(file_path.string().c_str(), "w"); @@ -263,8 +292,7 @@ void WifiConfigDialog::on_dpi_changed(const wxRect& suggested_rect) { SetFont(wxGetApp().normal_font()); - const int em = em_unit(); - + //const int em = em_unit(); //msw_buttons_rescale(this, em, { wxID_OK, wxID_CANCEL }); Fit(); diff --git a/src/slic3r/GUI/WifiConfigDialog.hpp b/src/slic3r/GUI/WifiConfigDialog.hpp index 08fa8cdc1b..b3c02b955b 100644 --- a/src/slic3r/GUI/WifiConfigDialog.hpp +++ b/src/slic3r/GUI/WifiConfigDialog.hpp @@ -20,7 +20,7 @@ class RemovableDriveManager; class WifiConfigDialog : public DPIDialog { public: - WifiConfigDialog(wxWindow* parent, std::string& file_path, RemovableDriveManager* removable_manager); + WifiConfigDialog(wxWindow* parent, std::string& file_path, RemovableDriveManager* removable_manager, const wxString& preffered_drive ); ~WifiConfigDialog(); private: ::ComboBox* m_ssid_combo {nullptr}; @@ -32,7 +32,7 @@ private: void on_rescan_drives(wxCommandEvent& e); void on_rescan_networks(wxCommandEvent& e); void on_retrieve_password(wxCommandEvent& e); - void rescan_drives(); + void rescan_drives(const wxString& preffered_drive); void rescan_networks(bool select); void fill_password(); // reference to string that is filled after ShowModal is called from owner