From e5c20cc81e33fa1c0d6591349f39bafcd9bdb8a5 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 26 Nov 2019 14:19:29 +0100 Subject: [PATCH 001/123] removable drive manager - Windows part --- src/slic3r/GUI/AppConfig.cpp | 5 + src/slic3r/GUI/RemovableDriveManager.cpp | 149 +++++++++++++++++++++++ src/slic3r/GUI/RemovableDriveManager.hpp | 41 +++++++ 3 files changed, 195 insertions(+) create mode 100644 src/slic3r/GUI/RemovableDriveManager.cpp create mode 100644 src/slic3r/GUI/RemovableDriveManager.hpp diff --git a/src/slic3r/GUI/AppConfig.cpp b/src/slic3r/GUI/AppConfig.cpp index 60f4edf478c..67d8bd8cf4b 100644 --- a/src/slic3r/GUI/AppConfig.cpp +++ b/src/slic3r/GUI/AppConfig.cpp @@ -21,6 +21,7 @@ #include #include "I18N.hpp" +#include "RemovableDriveManager.hpp" namespace Slic3r { @@ -357,6 +358,10 @@ void AppConfig::update_skein_dir(const std::string &dir) std::string AppConfig::get_last_output_dir(const std::string &alt) const { + if (GUI::RemovableDriveManager::getInstance().update()) + { + return GUI::RemovableDriveManager::getInstance().getLastDrivePath(); + } const auto it = m_storage.find(""); if (it != m_storage.end()) { const auto it2 = it->second.find("last_output_path"); diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp new file mode 100644 index 00000000000..44d4181d1b2 --- /dev/null +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -0,0 +1,149 @@ +#include "RemovableDriveManager.hpp" + +#include +#include +#include +#include + +//#include +//#include "libslic3r/Utils.hpp" + +DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, + 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED); + +namespace Slic3r { +namespace GUI { + +std::vector RemovableDriveManager::currentDrives; + +bool RemovableDriveManager::update() +{ + searchForDrives(currentDrives); + return !currentDrives.empty(); +} +void RemovableDriveManager::searchForDrives(std::vector& newDrives) +{ + newDrives.clear(); + newDrives.reserve(26); + DWORD drivesMask = GetLogicalDrives(); + for (size_t i = 0; i < 26; i++) + { + if(drivesMask & (1 << i)) + { + std::string path (1,(char)('A' + i)); + path+=":"; + UINT driveType = GetDriveTypeA(path.c_str()); + //std::cout << "found drive" << (char)('A' + i) << ": type:" < 0) + { + newDrives.push_back(DriveData(volumeName, path)); + } + } + } + } + else if(driveType == 3)//disks and usb drives + { + } + } + } + +} + +void RemovableDriveManager::updateCurrentDrives(const std::vector& newDrives) +{ + currentDrives.clear(); + currentDrives.reserve(26); + for (auto it = newDrives.begin(); it != newDrives.end(); ++it) + { + currentDrives.push_back(*it); + } +} +void RemovableDriveManager::printDrivesToLog() +{ + //std::cout<<"current drives:"<< currentDrives.size() <<"\n"; + for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + { + //BOOST_LOG_TRIVIAL(trace) << boost::format("found disk %1%:") % ('A' + i); + //std::cout << /*std::string((*it).name.begin(), (*it).name.end()) << "(" << */(*it).path << ":/, "; + } + //std::cout << "\n"; +} +bool RemovableDriveManager::isDriveMounted(std::string path) +{ + for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + { + if ((*it).path == path) + { + return true; + } + } + return false; +} +void RemovableDriveManager::ejectDrive(std::string path) +{ + if (!update() || !isDriveMounted(path)) + return; + + path = "\\\\.\\"+path; + HANDLE handle = CreateFileA(path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); + if(handle == INVALID_HANDLE_VALUE) + { + std::cerr << "Ejecting " << path << " failed " << GetLastError() << " \n"; + return; + } + DWORD deviceControlRetVal(0); + BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0,nullptr , 0, &deviceControlRetVal, nullptr); + CloseHandle(handle); + if(error != 0) + std::cout << "Ejected " << path << "\n"; + else + std::cerr << "Ejecting " << path << " failed "<< deviceControlRetVal << " " << GetLastError() <<" \n"; + + for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + { + if ((*it).path == path) + { + currentDrives.erase(it); + break; + } + } +} +std::string RemovableDriveManager::getLastDrivePath() +{ + if (!currentDrives.empty()) + { + return currentDrives.back().path; + } + return ""; +} +void RemovableDriveManager::getAllDrives(std::vector& drives) +{ + drives.clear(); + drives.reserve(26); + for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + { + drives.push_back(*it); + } +} +}} \ No newline at end of file diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp new file mode 100644 index 00000000000..cab58fee6c8 --- /dev/null +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -0,0 +1,41 @@ +#ifndef slic3r_GUI_RemovableDriveManager_hpp_ +#define slic3r_GUI_RemovableDriveManager_hpp_ + +#include +#include + +namespace Slic3r { +namespace GUI { +struct DriveData +{ + std::wstring name; + std::string path; + DriveData(std::wstring n, std::string p):name(n),path(p){} +}; +class RemovableDriveManager +{ +public: + static RemovableDriveManager& getInstance() + { + static RemovableDriveManager instance; + return instance; + } + RemovableDriveManager(RemovableDriveManager const&) = delete; + void operator=(RemovableDriveManager const&) = delete; + + //update() searches for removable devices, returns false if empty. + static bool update(); + static bool isDriveMounted(std::string path); + static void ejectDrive(std::string path); + static std::string getLastDrivePath(); + static void getAllDrives(std::vector& drives); +private: + RemovableDriveManager(){} + static void searchForDrives(std::vector& newDrives); + static void printDrivesToLog(); + static void updateCurrentDrives(const std::vector& newDrives); + static std::vector currentDrives; + +}; +}} +#endif \ No newline at end of file From 8223e3fbfa11f7c7f703edeadb0520060475f4e0 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 26 Nov 2019 15:52:18 +0100 Subject: [PATCH 002/123] removable drives manager linux part --- src/slic3r/CMakeLists.txt | 2 + src/slic3r/GUI/RemovableDriveManager.cpp | 166 +++++++++++++++++------ src/slic3r/GUI/RemovableDriveManager.hpp | 10 +- 3 files changed, 134 insertions(+), 44 deletions(-) diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 6dcbc60b71b..bb196d3fdec 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -109,6 +109,8 @@ set(SLIC3R_GUI_SOURCES GUI/WipeTowerDialog.hpp GUI/RammingChart.cpp GUI/RammingChart.hpp + GUI/RemovableDriveManager.cpp + GUI/RemovableDriveManager.hpp GUI/BonjourDialog.cpp GUI/BonjourDialog.hpp GUI/ButtonsDescription.cpp diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 44d4181d1b2..ae718b7d3a8 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -1,26 +1,34 @@ #include "RemovableDriveManager.hpp" -#include -#include + + #include #include -//#include -//#include "libslic3r/Utils.hpp" +#if _WIN32 +#include +#include DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED); +#else +//linux includes +#include +#include +#include +#include +#include +#endif namespace Slic3r { namespace GUI { std::vector RemovableDriveManager::currentDrives; -bool RemovableDriveManager::update() -{ - searchForDrives(currentDrives); - return !currentDrives.empty(); -} + + + +#if _WIN32 void RemovableDriveManager::searchForDrives(std::vector& newDrives) { newDrives.clear(); @@ -69,37 +77,6 @@ void RemovableDriveManager::searchForDrives(std::vector& newDrives) } } - -void RemovableDriveManager::updateCurrentDrives(const std::vector& newDrives) -{ - currentDrives.clear(); - currentDrives.reserve(26); - for (auto it = newDrives.begin(); it != newDrives.end(); ++it) - { - currentDrives.push_back(*it); - } -} -void RemovableDriveManager::printDrivesToLog() -{ - //std::cout<<"current drives:"<< currentDrives.size() <<"\n"; - for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) - { - //BOOST_LOG_TRIVIAL(trace) << boost::format("found disk %1%:") % ('A' + i); - //std::cout << /*std::string((*it).name.begin(), (*it).name.end()) << "(" << */(*it).path << ":/, "; - } - //std::cout << "\n"; -} -bool RemovableDriveManager::isDriveMounted(std::string path) -{ - for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) - { - if ((*it).path == path) - { - return true; - } - } - return false; -} void RemovableDriveManager::ejectDrive(std::string path) { if (!update() || !isDriveMounted(path)) @@ -129,6 +106,115 @@ void RemovableDriveManager::ejectDrive(std::string path) } } } +#else +void RemovableDriveManager::searchForDrives(std::vector& newDrives) +{ + struct stat buf; + std::string path(std::getenv("USER")); + std::string pp(path); + + newDrives.clear(); + newDrives.reserve(26); + + //search /media/* folder + stat("/media/",&buf); + std::cout << "/media ID: " <& newDrives,const std::string path, const dev_t parentDevID) +{ + glob_t globbuf; + globbuf.gl_offs = 2; + std::cout<<"searching "<& newDrives) +{ + currentDrives.clear(); + currentDrives.reserve(26); + for (auto it = newDrives.begin(); it != newDrives.end(); ++it) + { + currentDrives.push_back(*it); + } +} +bool RemovableDriveManager::isDriveMounted(std::string path) +{ + for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + { + if ((*it).path == path) + { + return true; + } + } + return false; +} + std::string RemovableDriveManager::getLastDrivePath() { if (!currentDrives.empty()) diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index cab58fee6c8..c503fdf1873 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -8,9 +8,9 @@ namespace Slic3r { namespace GUI { struct DriveData { - std::wstring name; + std::string name; std::string path; - DriveData(std::wstring n, std::string p):name(n),path(p){} + DriveData(std::string n, std::string p):name(n),path(p){} }; class RemovableDriveManager { @@ -32,10 +32,12 @@ public: private: RemovableDriveManager(){} static void searchForDrives(std::vector& newDrives); - static void printDrivesToLog(); static void updateCurrentDrives(const std::vector& newDrives); static std::vector currentDrives; - +#if _WIN32 +#else + static void searchPath(std::vector& newDrives,const std::string path, const dev_t parentDevID); +#endif }; }} #endif \ No newline at end of file From 4997c7738804db9b06f032b7e6b6b09f61221a31 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 27 Nov 2019 11:33:36 +0100 Subject: [PATCH 003/123] refactoring --- src/slic3r/GUI/AppConfig.cpp | 2 +- src/slic3r/GUI/RemovableDriveManager.cpp | 116 ++++++++++------------- src/slic3r/GUI/RemovableDriveManager.hpp | 15 ++- 3 files changed, 58 insertions(+), 75 deletions(-) diff --git a/src/slic3r/GUI/AppConfig.cpp b/src/slic3r/GUI/AppConfig.cpp index 67d8bd8cf4b..320f3375155 100644 --- a/src/slic3r/GUI/AppConfig.cpp +++ b/src/slic3r/GUI/AppConfig.cpp @@ -360,7 +360,7 @@ std::string AppConfig::get_last_output_dir(const std::string &alt) const { if (GUI::RemovableDriveManager::getInstance().update()) { - return GUI::RemovableDriveManager::getInstance().getLastDrivePath(); + return GUI::RemovableDriveManager::getInstance().get_last_drive_path(); } const auto it = m_storage.find(""); if (it != m_storage.end()) { diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index ae718b7d3a8..53515ccdcba 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -1,14 +1,12 @@ #include "RemovableDriveManager.hpp" - - - #include #include - +#include "boost/nowide/convert.hpp" #if _WIN32 #include #include +#include DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED); #else @@ -23,16 +21,13 @@ DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, namespace Slic3r { namespace GUI { -std::vector RemovableDriveManager::currentDrives; - - - +std::vector RemovableDriveManager::m_current_drives; #if _WIN32 -void RemovableDriveManager::searchForDrives(std::vector& newDrives) +void RemovableDriveManager::search_for_drives() { - newDrives.clear(); - newDrives.reserve(26); + m_current_drives.clear(); + m_current_drives.reserve(26); DWORD drivesMask = GetLogicalDrives(); for (size_t i = 0; i < 26; i++) { @@ -65,7 +60,7 @@ void RemovableDriveManager::searchForDrives(std::vector& newDrives) //std::cout << std::string(volumeName.begin(), volumeName.end()) << " " << std::string(fileSystemName.begin(), fileSystemName.end()) << " " << freeSpace.QuadPart << "\n"; if (freeSpace.QuadPart > 0) { - newDrives.push_back(DriveData(volumeName, path)); + m_current_drives.push_back(DriveData(boost::nowide::narrow(volumeName), path)); } } } @@ -77,49 +72,51 @@ void RemovableDriveManager::searchForDrives(std::vector& newDrives) } } -void RemovableDriveManager::ejectDrive(std::string path) +void RemovableDriveManager::eject_drive(const std::string &path) { - if (!update() || !isDriveMounted(path)) - return; - path = "\\\\.\\"+path; - HANDLE handle = CreateFileA(path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); - if(handle == INVALID_HANDLE_VALUE) - { - std::cerr << "Ejecting " << path << " failed " << GetLastError() << " \n"; + //if (!update() || !is_drive_mounted(path)) + if(m_current_drives.empty()) return; - } - DWORD deviceControlRetVal(0); - BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0,nullptr , 0, &deviceControlRetVal, nullptr); - CloseHandle(handle); - if(error != 0) - std::cout << "Ejected " << path << "\n"; - else - std::cerr << "Ejecting " << path << " failed "<< deviceControlRetVal << " " << GetLastError() <<" \n"; - - for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) { if ((*it).path == path) { - currentDrives.erase(it); + std::string mpath = "\\\\.\\" + path; + HANDLE handle = CreateFileA(mpath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); + if (handle == INVALID_HANDLE_VALUE) + { + std::cerr << "Ejecting " << mpath << " failed " << GetLastError() << " \n"; + return; + } + DWORD deviceControlRetVal(0); + BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); + CloseHandle(handle); + if (error != 0) + std::cout << "Ejected " << mpath << "\n"; + else + std::cerr << "Ejecting " << mpath << " failed " << deviceControlRetVal << " " << GetLastError() << " \n"; + + + m_current_drives.erase(it); break; } } } #else -void RemovableDriveManager::searchForDrives(std::vector& newDrives) +void RemovableDriveManager::search_for_drives() { struct stat buf; std::string path(std::getenv("USER")); std::string pp(path); - newDrives.clear(); - newDrives.reserve(26); + m_current_drives.clear(); + m_current_Drives.reserve(26); //search /media/* folder stat("/media/",&buf); std::cout << "/media ID: " <& newDrives) stat(pp.c_str() ,&buf); std::cout << pp <<" ID: " <& newDrives,const std::string path, const dev_t parentDevID) +void RemovableDriveManager::search_path(const std::string &path,const dev_t &parentDevID) { glob_t globbuf; globbuf.gl_offs = 2; @@ -159,17 +156,17 @@ void RemovableDriveManager::searchPath(std::vector& newDrives,const s std::cout << buf.st_dev << "\n"; if(buf.st_dev != parentDevID)// not same file system { - newDrives.push_back(DriveData(name,globbuf.gl_pathv[i])); + m_current_drives.push_back(DriveData(name,globbuf.gl_pathv[i])); } } globfree(&globbuf); } -void RemovableDriveManager::ejectDrive(std::string path) +void RemovableDriveManager::eject_drive(const std::string &path) { - if (currentDrives.empty()) + if (m_current_drives.empty()) return; - for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) { if((*it).path == path) { @@ -180,7 +177,7 @@ void RemovableDriveManager::ejectDrive(std::string path) int errsv = errno; std::cerr<<"Ejecting failed Error "<< errsv<<"\n"; } - currentDrives.erase(it); + m_current_drives.erase(it); break; } @@ -190,22 +187,14 @@ void RemovableDriveManager::ejectDrive(std::string path) #endif bool RemovableDriveManager::update() { - searchForDrives(currentDrives); - return !currentDrives.empty(); + search_for_drives(); + return !m_current_drives.empty(); } -void RemovableDriveManager::updateCurrentDrives(const std::vector& newDrives) + +bool RemovableDriveManager::is_drive_mounted(const std::string &path) { - currentDrives.clear(); - currentDrives.reserve(26); - for (auto it = newDrives.begin(); it != newDrives.end(); ++it) - { - currentDrives.push_back(*it); - } -} -bool RemovableDriveManager::isDriveMounted(std::string path) -{ - for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) { if ((*it).path == path) { @@ -215,21 +204,16 @@ bool RemovableDriveManager::isDriveMounted(std::string path) return false; } -std::string RemovableDriveManager::getLastDrivePath() +std::string RemovableDriveManager::get_last_drive_path() { - if (!currentDrives.empty()) + if (!m_current_drives.empty()) { - return currentDrives.back().path; + return m_current_drives.back().path; } return ""; } -void RemovableDriveManager::getAllDrives(std::vector& drives) +std::vector RemovableDriveManager::get_all_drives() { - drives.clear(); - drives.reserve(26); - for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) - { - drives.push_back(*it); - } + return m_current_drives; } }} \ No newline at end of file diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index c503fdf1873..8270c0f0fba 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -25,18 +25,17 @@ public: //update() searches for removable devices, returns false if empty. static bool update(); - static bool isDriveMounted(std::string path); - static void ejectDrive(std::string path); - static std::string getLastDrivePath(); - static void getAllDrives(std::vector& drives); + static bool is_drive_mounted(const std::string &path); + static void eject_drive(const std::string &path); + static std::string get_last_drive_path(); + static std::vector get_all_drives(); private: RemovableDriveManager(){} - static void searchForDrives(std::vector& newDrives); - static void updateCurrentDrives(const std::vector& newDrives); - static std::vector currentDrives; + static void search_for_drives(); + static std::vector m_current_drives; #if _WIN32 #else - static void searchPath(std::vector& newDrives,const std::string path, const dev_t parentDevID); + static void search_path(const std::string &path, const dev_t &parentDevID); #endif }; }} From 52437a125b8fc0a547f4c826995f8a2b1743944d Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 27 Nov 2019 13:30:45 +0100 Subject: [PATCH 004/123] check if last path is on rem drive --- src/slic3r/GUI/AppConfig.cpp | 6 +---- src/slic3r/GUI/Plater.cpp | 9 ++++++- src/slic3r/GUI/RemovableDriveManager.cpp | 30 +++++++++++++++++++++++- src/slic3r/GUI/RemovableDriveManager.hpp | 1 + 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/slic3r/GUI/AppConfig.cpp b/src/slic3r/GUI/AppConfig.cpp index 320f3375155..16f0459664e 100644 --- a/src/slic3r/GUI/AppConfig.cpp +++ b/src/slic3r/GUI/AppConfig.cpp @@ -21,7 +21,6 @@ #include #include "I18N.hpp" -#include "RemovableDriveManager.hpp" namespace Slic3r { @@ -358,10 +357,7 @@ void AppConfig::update_skein_dir(const std::string &dir) std::string AppConfig::get_last_output_dir(const std::string &alt) const { - if (GUI::RemovableDriveManager::getInstance().update()) - { - return GUI::RemovableDriveManager::getInstance().get_last_drive_path(); - } + const auto it = m_storage.find(""); if (it != m_storage.end()) { const auto it2 = it->second.find("last_output_path"); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 789271581ea..bbfa9d93287 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -77,6 +77,7 @@ #include "../Utils/FixModelByWin10.hpp" #include "../Utils/UndoRedo.hpp" #include "../Utils/Thread.hpp" +#include "RemovableDriveManager.hpp" #include // Needs to be last because reasons :-/ #include "WipeTowerDialog.hpp" @@ -4549,7 +4550,13 @@ void Plater::export_gcode() } default_output_file = fs::path(Slic3r::fold_utf8_to_ascii(default_output_file.string())); auto start_dir = wxGetApp().app_config->get_last_output_dir(default_output_file.parent_path().string()); - + if (GUI::RemovableDriveManager::getInstance().update()) + { + if (!RemovableDriveManager::getInstance().is_path_on_removable_drive(start_dir)) + { + start_dir = RemovableDriveManager::getInstance().get_last_drive_path(); + } + } wxFileDialog dlg(this, (printer_technology() == ptFFF) ? _(L("Save G-code file as:")) : _(L("Save SL1 file as:")), start_dir, from_path(default_output_file.filename()), diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 53515ccdcba..776334bf22c 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -7,6 +7,7 @@ #include #include #include +#include DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED); #else @@ -208,7 +209,11 @@ std::string RemovableDriveManager::get_last_drive_path() { if (!m_current_drives.empty()) { +#if _WIN32 + return m_current_drives.back().path + "\\"; +#else return m_current_drives.back().path; +#endif } return ""; } @@ -216,4 +221,27 @@ std::vector RemovableDriveManager::get_all_drives() { return m_current_drives; } -}} \ No newline at end of file +#if _WIN32 +bool RemovableDriveManager::is_path_on_removable_drive(const std::string& path) +{ + if (m_current_drives.empty()) + return false; + int letter = PathGetDriveNumberA(path.c_str()); + for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) + { + char drive = (*it).path[0]; + if (drive == ('A' + letter)) + return true; + } + return false; +} +#else +bool RemovableDriveManager::is_path_on_removable_drive(const std::string& path, const std::string& drive) +{ + if (m_current_drives.empty()) + return false; + + return false; +} +#endif +}}//namespace Slicer::Gui:: \ No newline at end of file diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 8270c0f0fba..3de9d72cee7 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -29,6 +29,7 @@ public: static void eject_drive(const std::string &path); static std::string get_last_drive_path(); static std::vector get_all_drives(); + static bool is_path_on_removable_drive(const std::string &path); private: RemovableDriveManager(){} static void search_for_drives(); From 455b0125ce1c5bf6ff829566de032b4d76ec36ed Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 27 Nov 2019 14:30:10 +0100 Subject: [PATCH 005/123] prev commit linux part --- src/slic3r/GUI/RemovableDriveManager.cpp | 139 ++++++++++++----------- 1 file changed, 75 insertions(+), 64 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 776334bf22c..2d1f4ba6f2e 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -29,46 +29,43 @@ void RemovableDriveManager::search_for_drives() { m_current_drives.clear(); m_current_drives.reserve(26); - DWORD drivesMask = GetLogicalDrives(); + DWORD drives_mask = GetLogicalDrives(); for (size_t i = 0; i < 26; i++) { - if(drivesMask & (1 << i)) + if(drives_mask & (1 << i)) { std::string path (1,(char)('A' + i)); path+=":"; - UINT driveType = GetDriveTypeA(path.c_str()); + UINT drive_type = GetDriveTypeA(path.c_str()); //std::cout << "found drive" << (char)('A' + i) << ": type:" < 0) + if (free_space.QuadPart > 0) { - m_current_drives.push_back(DriveData(boost::nowide::narrow(volumeName), path)); + m_current_drives.push_back(DriveData(boost::nowide::narrow(volume_name), path)); } } } } - else if(driveType == 3)//disks and usb drives - { - } } } @@ -93,10 +90,10 @@ void RemovableDriveManager::eject_drive(const std::string &path) DWORD deviceControlRetVal(0); BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); CloseHandle(handle); - if (error != 0) - std::cout << "Ejected " << mpath << "\n"; - else + if (error == 0) + { std::cerr << "Ejecting " << mpath << " failed " << deviceControlRetVal << " " << GetLastError() << " \n"; + } m_current_drives.erase(it); @@ -104,6 +101,19 @@ void RemovableDriveManager::eject_drive(const std::string &path) } } } +bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path) +{ + if (m_current_drives.empty()) + return false; + int letter = PathGetDriveNumberA(path.c_str()); + for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) + { + char drive = (*it).path[0]; + if (drive == ('A' + letter)) + return true; + } + return false; +} #else void RemovableDriveManager::search_for_drives() { @@ -112,11 +122,11 @@ void RemovableDriveManager::search_for_drives() std::string pp(path); m_current_drives.clear(); - m_current_Drives.reserve(26); + m_current_drives.reserve(26); //search /media/* folder stat("/media/",&buf); - std::cout << "/media ID: " < RemovableDriveManager::get_all_drives() return m_current_drives; } #if _WIN32 -bool RemovableDriveManager::is_path_on_removable_drive(const std::string& path) -{ - if (m_current_drives.empty()) - return false; - int letter = PathGetDriveNumberA(path.c_str()); - for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) - { - char drive = (*it).path[0]; - if (drive == ('A' + letter)) - return true; - } - return false; -} -#else -bool RemovableDriveManager::is_path_on_removable_drive(const std::string& path, const std::string& drive) -{ - if (m_current_drives.empty()) - return false; - return false; -} +#else + #endif }}//namespace Slicer::Gui:: \ No newline at end of file From 1bc7c896a9c9672fca0107c2d3a58b1f480601b2 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 27 Nov 2019 15:47:37 +0100 Subject: [PATCH 006/123] rdm update every 2 seconds --- src/slic3r/GUI/GUI_App.cpp | 2 ++ src/slic3r/GUI/RemovableDriveManager.cpp | 15 ++++++++++++++- src/slic3r/GUI/RemovableDriveManager.hpp | 3 ++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index a74c6b0c069..35c11f0211f 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -46,6 +46,7 @@ #include "SysInfoDialog.hpp" #include "KBShortcutsDialog.hpp" #include "UpdateDialogs.hpp" +#include "RemovableDriveManager.hpp" #ifdef __WXMSW__ #include @@ -269,6 +270,7 @@ bool GUI_App::on_init_inner() this->obj_manipul()->update_if_dirty(); + RemovableDriveManager::getInstance().update(wxGetLocalTime()); // Preset updating & Configwizard are done after the above initializations, // and after MainFrame is created & shown. // The extra CallAfter() is needed because of Mac, where this is the only way diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 2d1f4ba6f2e..235e1ccbe84 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -23,6 +23,7 @@ namespace Slic3r { namespace GUI { std::vector RemovableDriveManager::m_current_drives; +long RemovableDriveManager::m_last_update = 0; #if _WIN32 void RemovableDriveManager::search_for_drives() @@ -215,8 +216,20 @@ bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path) return false; } #endif -bool RemovableDriveManager::update() +bool RemovableDriveManager::update(long time) { + if(time != 0) //time = 0 is forced update + { + long diff = m_last_update - time; + if(diff <= -2) + { + m_last_update = time; + }else + { + return false; // return value shouldnt matter if update didnt run + } + } + std::cout << "RDM update " << m_last_update <<"\n"; search_for_drives(); return !m_current_drives.empty(); } diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 3de9d72cee7..c83b8033c98 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -24,7 +24,7 @@ public: void operator=(RemovableDriveManager const&) = delete; //update() searches for removable devices, returns false if empty. - static bool update(); + static bool update(long time = 0); //time = 0 is forced update static bool is_drive_mounted(const std::string &path); static void eject_drive(const std::string &path); static std::string get_last_drive_path(); @@ -34,6 +34,7 @@ private: RemovableDriveManager(){} static void search_for_drives(); static std::vector m_current_drives; + static long m_last_update; #if _WIN32 #else static void search_path(const std::string &path, const dev_t &parentDevID); From 151f180827701adaa8a24979658df4a860d82f1a Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 28 Nov 2019 13:38:08 +0100 Subject: [PATCH 007/123] add_callback function --- src/slic3r/GUI/RemovableDriveManager.cpp | 65 ++++++++++++++++++++---- src/slic3r/GUI/RemovableDriveManager.hpp | 6 ++- 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 235e1ccbe84..a1a5d7dd927 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -23,7 +23,8 @@ namespace Slic3r { namespace GUI { std::vector RemovableDriveManager::m_current_drives; -long RemovableDriveManager::m_last_update = 0; +std::vector> RemovableDriveManager::m_callbacks; + #if _WIN32 void RemovableDriveManager::search_for_drives() @@ -69,7 +70,7 @@ void RemovableDriveManager::search_for_drives() } } } - + //std::cout << "found drives:" << m_current_drives.size() << "\n"; } void RemovableDriveManager::eject_drive(const std::string &path) { @@ -115,6 +116,25 @@ bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path) } return false; } +void RemovableDriveManager::register_window() +{ + /* + WNDCLASSEX wndClass; + + wndClass.cbSize = sizeof(WNDCLASSEX); + wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; + wndClass.hInstance = reinterpret_cast(GetModuleHandle(0)); + wndClass.lpfnWndProc = reinterpret_cast(WinProcCallback); + wndClass.cbClsExtra = 0; + wndClass.cbWndExtra = 0; + wndClass.hIcon = LoadIcon(0, IDI_APPLICATION); + wndClass.hbrBackground = CreateSolidBrush(RGB(192, 192, 192)); + wndClass.hCursor = LoadCursor(0, IDC_ARROW); + wndClass.lpszClassName = L"SlicerWindowClass"; + wndClass.lpszMenuName = NULL; + wndClass.hIconSm = wndClass.hIcon; + */ +} #else void RemovableDriveManager::search_for_drives() { @@ -218,19 +238,29 @@ bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path) #endif bool RemovableDriveManager::update(long time) { + static long last_update = 0; + if(last_update == 0) + { + //add_callback(std::bind(&RemovableDriveManager::print, RemovableDriveManager::getInstance())); + add_callback([](void) { print(); }); +#if _WIN32 + register_window(); +#endif + } if(time != 0) //time = 0 is forced update { - long diff = m_last_update - time; + long diff = last_update - time; if(diff <= -2) { - m_last_update = time; + last_update = time; }else { return false; // return value shouldnt matter if update didnt run } } - std::cout << "RDM update " << m_last_update <<"\n"; + //std::cout << "RDM update " << last_update <<"\n"; search_for_drives(); + check_and_notify(); return !m_current_drives.empty(); } @@ -263,9 +293,24 @@ std::vector RemovableDriveManager::get_all_drives() { return m_current_drives; } -#if _WIN32 - -#else - -#endif +void RemovableDriveManager::check_and_notify() +{ + static int number_of_drives = 0; + if(number_of_drives != m_current_drives.size()) + { + for (auto it = m_callbacks.begin(); it != m_callbacks.end(); ++it) + { + (*it)(); + } + number_of_drives = m_current_drives.size(); + } +} +void RemovableDriveManager::add_callback(std::function callback) +{ + m_callbacks.push_back(callback); +} +void RemovableDriveManager::print() +{ + std::cout << "notified\n"; +} }}//namespace Slicer::Gui:: \ No newline at end of file diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index c83b8033c98..9f3ebf326b1 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -30,12 +30,16 @@ public: static std::string get_last_drive_path(); static std::vector get_all_drives(); static bool is_path_on_removable_drive(const std::string &path); + static void add_callback(std::function callback); + static void print(); private: RemovableDriveManager(){} static void search_for_drives(); + static void check_and_notify(); static std::vector m_current_drives; - static long m_last_update; + static std::vector> m_callbacks; #if _WIN32 + static void register_window(); #else static void search_path(const std::string &path, const dev_t &parentDevID); #endif From a8b93a20b245803b0ac63e5113fa0fcaec2937f0 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 28 Nov 2019 13:50:58 +0100 Subject: [PATCH 008/123] refactoring --- src/slic3r/GUI/GUI_App.cpp | 2 +- src/slic3r/GUI/Plater.cpp | 6 ++--- src/slic3r/GUI/RemovableDriveManager.cpp | 6 ++--- src/slic3r/GUI/RemovableDriveManager.hpp | 30 ++++++++++++------------ 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 35c11f0211f..10eb4ab59b8 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -270,7 +270,7 @@ bool GUI_App::on_init_inner() this->obj_manipul()->update_if_dirty(); - RemovableDriveManager::getInstance().update(wxGetLocalTime()); + RemovableDriveManager::get_instance().update(wxGetLocalTime()); // Preset updating & Configwizard are done after the above initializations, // and after MainFrame is created & shown. // The extra CallAfter() is needed because of Mac, where this is the only way diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index bbfa9d93287..74b2d12391f 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4550,11 +4550,11 @@ void Plater::export_gcode() } default_output_file = fs::path(Slic3r::fold_utf8_to_ascii(default_output_file.string())); auto start_dir = wxGetApp().app_config->get_last_output_dir(default_output_file.parent_path().string()); - if (GUI::RemovableDriveManager::getInstance().update()) + if (GUI::RemovableDriveManager::get_instance().update()) { - if (!RemovableDriveManager::getInstance().is_path_on_removable_drive(start_dir)) + if (!RemovableDriveManager::get_instance().is_path_on_removable_drive(start_dir)) { - start_dir = RemovableDriveManager::getInstance().get_last_drive_path(); + start_dir = RemovableDriveManager::get_instance().get_last_drive_path(); } } wxFileDialog dlg(this, (printer_technology() == ptFFF) ? _(L("Save G-code file as:")) : _(L("Save SL1 file as:")), diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index a1a5d7dd927..777085165de 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -22,8 +22,8 @@ DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, namespace Slic3r { namespace GUI { -std::vector RemovableDriveManager::m_current_drives; -std::vector> RemovableDriveManager::m_callbacks; +//std::vector RemovableDriveManager::m_current_drives; +//std::vector> RemovableDriveManager::m_callbacks; #if _WIN32 @@ -242,7 +242,7 @@ bool RemovableDriveManager::update(long time) if(last_update == 0) { //add_callback(std::bind(&RemovableDriveManager::print, RemovableDriveManager::getInstance())); - add_callback([](void) { print(); }); + add_callback([](void) { RemovableDriveManager::get_instance().print(); }); #if _WIN32 register_window(); #endif diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 9f3ebf326b1..f3abc420739 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -15,7 +15,7 @@ struct DriveData class RemovableDriveManager { public: - static RemovableDriveManager& getInstance() + static RemovableDriveManager& get_instance() { static RemovableDriveManager instance; return instance; @@ -24,24 +24,24 @@ public: void operator=(RemovableDriveManager const&) = delete; //update() searches for removable devices, returns false if empty. - static bool update(long time = 0); //time = 0 is forced update - static bool is_drive_mounted(const std::string &path); - static void eject_drive(const std::string &path); - static std::string get_last_drive_path(); - static std::vector get_all_drives(); - static bool is_path_on_removable_drive(const std::string &path); - static void add_callback(std::function callback); - static void print(); + bool update(long time = 0); //time = 0 is forced update + bool is_drive_mounted(const std::string &path); + void eject_drive(const std::string &path); + std::string get_last_drive_path(); + std::vector get_all_drives(); + bool is_path_on_removable_drive(const std::string &path); + void add_callback(std::function callback); + void print(); private: RemovableDriveManager(){} - static void search_for_drives(); - static void check_and_notify(); - static std::vector m_current_drives; - static std::vector> m_callbacks; + void search_for_drives(); + void check_and_notify(); + std::vector m_current_drives; + std::vector> m_callbacks; #if _WIN32 - static void register_window(); + void register_window(); #else - static void search_path(const std::string &path, const dev_t &parentDevID); + void search_path(const std::string &path, const dev_t &parentDevID); #endif }; }} From 7171ebb159136347e050f096fd7e42c0234069b7 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 28 Nov 2019 16:35:22 +0100 Subject: [PATCH 009/123] search for rd as root --- src/slic3r/GUI/RemovableDriveManager.cpp | 103 +++++++++++++---------- src/slic3r/GUI/RemovableDriveManager.hpp | 3 +- 2 files changed, 61 insertions(+), 45 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 777085165de..4368d06b647 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -1,6 +1,5 @@ #include "RemovableDriveManager.hpp" #include -#include #include "boost/nowide/convert.hpp" #if _WIN32 @@ -17,6 +16,7 @@ DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, #include #include #include +#include #endif namespace Slic3r { @@ -96,8 +96,6 @@ void RemovableDriveManager::eject_drive(const std::string &path) { std::cerr << "Ejecting " << mpath << " failed " << deviceControlRetVal << " " << GetLastError() << " \n"; } - - m_current_drives.erase(it); break; } @@ -138,65 +136,85 @@ void RemovableDriveManager::register_window() #else void RemovableDriveManager::search_for_drives() { - struct stat buf; - std::string path(std::getenv("USER")); - std::string pp(path); - + m_current_drives.clear(); m_current_drives.reserve(26); //search /media/* folder - stat("/media/",&buf); - //std::cout << "/media ID: " <pw_name; + pp = path; + //search /media/USERNAME/* folder + pp = "/media/"+pp; + path = "/media/" + path + "/*"; + search_path(path, pp); - stat(pp.c_str() ,&buf); - //std::cout << pp <<" ID: " < RemovableDriveManager::get_all_drives() } void RemovableDriveManager::check_and_notify() { - static int number_of_drives = 0; + static size_t number_of_drives = 0; if(number_of_drives != m_current_drives.size()) { for (auto it = m_callbacks.begin(); it != m_callbacks.end(); ++it) diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index f3abc420739..43e47a08671 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -41,7 +41,8 @@ private: #if _WIN32 void register_window(); #else - void search_path(const std::string &path, const dev_t &parentDevID); + void search_path(const std::string &path, const std::string &parent_path); + bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); #endif }; }} From 5175c36d25bbfe40eecae59106e2a7232e3d547f Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 3 Dec 2019 10:09:53 +0100 Subject: [PATCH 010/123] linux eject --- src/slic3r/GUI/GUI_App.cpp | 1 + src/slic3r/GUI/RemovableDriveManager.cpp | 29 ++++++++++++++---------- src/slic3r/GUI/RemovableDriveManager.hpp | 3 ++- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 10eb4ab59b8..c36c2748dd9 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -271,6 +271,7 @@ bool GUI_App::on_init_inner() this->obj_manipul()->update_if_dirty(); RemovableDriveManager::get_instance().update(wxGetLocalTime()); + // Preset updating & Configwizard are done after the above initializations, // and after MainFrame is created & shown. // The extra CallAfter() is needed because of Mac, where this is the only way diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 4368d06b647..ec730692fa2 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -20,8 +20,7 @@ DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, #endif namespace Slic3r { -namespace GUI { - +namespace GUI { //std::vector RemovableDriveManager::m_current_drives; //std::vector> RemovableDriveManager::m_callbacks; @@ -95,7 +94,10 @@ void RemovableDriveManager::eject_drive(const std::string &path) if (error == 0) { std::cerr << "Ejecting " << mpath << " failed " << deviceControlRetVal << " " << GetLastError() << " \n"; + return; } + + m_current_drives.erase(it); break; } @@ -179,7 +181,7 @@ void RemovableDriveManager::search_for_drives() } - std::cout << "found drives:" < RemovableDriveManager::get_all_drives() } void RemovableDriveManager::check_and_notify() { - static size_t number_of_drives = 0; - if(number_of_drives != m_current_drives.size()) + //std::cout<<"drives count: "< callback) { diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 43e47a08671..b465b1c1b81 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -33,11 +33,12 @@ public: void add_callback(std::function callback); void print(); private: - RemovableDriveManager(){} + RemovableDriveManager():m_drives_count(0){} void search_for_drives(); void check_and_notify(); std::vector m_current_drives; std::vector> m_callbacks; + size_t m_drives_count; #if _WIN32 void register_window(); #else From 1c8082a2b5fccea032d59dac5d775d1e6b0284c0 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 3 Dec 2019 10:55:38 +0100 Subject: [PATCH 011/123] windows paths --- src/slic3r/GUI/RemovableDriveManager.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index ec730692fa2..9b3020e79ef 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -62,6 +62,7 @@ void RemovableDriveManager::search_for_drives() //std::cout << std::string(volumeName.begin(), volumeName.end()) << " " << std::string(fileSystemName.begin(), fileSystemName.end()) << " " << freeSpace.QuadPart << "\n"; if (free_space.QuadPart > 0) { + path += "\\"; m_current_drives.push_back(DriveData(boost::nowide::narrow(volume_name), path)); } } @@ -82,6 +83,8 @@ void RemovableDriveManager::eject_drive(const std::string &path) if ((*it).path == path) { std::string mpath = "\\\\.\\" + path; + mpath = mpath.substr(0, mpath.size() - 1); + std::cout << "Ejecting " << mpath << "\n"; HANDLE handle = CreateFileA(mpath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); if (handle == INVALID_HANDLE_VALUE) { @@ -299,11 +302,11 @@ std::string RemovableDriveManager::get_last_drive_path() { if (!m_current_drives.empty()) { -#if _WIN32 - return m_current_drives.back().path + "\\"; -#else +//#if _WIN32 +// return m_current_drives.back().path + "\\"; +//#else return m_current_drives.back().path; -#endif +//#endif } return ""; } From 7b4b6abdeb061165a9e73b748c957243b8fb83b2 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 4 Dec 2019 10:05:18 +0100 Subject: [PATCH 012/123] osx search for drives --- src/slic3r/GUI/RemovableDriveManager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 9b3020e79ef..bdc1727403e 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -148,6 +148,9 @@ void RemovableDriveManager::search_for_drives() //search /media/* folder search_path("/media/*", "/media"); + //search /Volumes/* folder (OSX) + search_path("/Volumes/*", "/Volumes"); + std::string path(std::getenv("USER")); std::string pp(path); //std::cout << "user: "<< path << "\n"; From 17df533cbb361ae1fc7a6d9fa456852fc71b3a14 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 4 Dec 2019 11:47:47 +0100 Subject: [PATCH 013/123] linux owner checking --- src/slic3r/GUI/RemovableDriveManager.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index bdc1727403e..99520b84297 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -154,7 +154,10 @@ void RemovableDriveManager::search_for_drives() std::string path(std::getenv("USER")); std::string pp(path); //std::cout << "user: "<< path << "\n"; - if(path == "root"){ //if program is run with sudo, we have to search for all users + //if program is run with sudo, we have to search for all users + // but do we want that? + /* + if(path == "root"){ while (true) { passwd* entry = getpwent(); if (!entry) { @@ -174,6 +177,7 @@ void RemovableDriveManager::search_for_drives() } endpwent(); }else + */ { //search /media/USERNAME/* folder pp = "/media/"+pp; @@ -187,7 +191,7 @@ void RemovableDriveManager::search_for_drives() } - //std::cout << "found drives:" <pw_name == username) + { + std::string name = basename(globbuf.gl_pathv[i]); + m_current_drives.push_back(DriveData(name,globbuf.gl_pathv[i])); + } + } } } }else From 1fffd17c3be8db120ecde1707163bdb00bc1edf4 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 4 Dec 2019 13:10:08 +0100 Subject: [PATCH 014/123] path check --- src/slic3r/GUI/RemovableDriveManager.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 99520b84297..e1ab1626c5c 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -248,6 +248,15 @@ void RemovableDriveManager::eject_drive(const std::string &path) { if((*it).path == path) { + + std::string correct_path(path); + for (size_t i = 0; i < correct_path.size(); ++i) + { + if(correct_path[i]==' ') + { + correct_path = correct_path.insert(i,"\\"); + } + } std::cout<<"Ejecting "<<(*it).name<<" from "<< (*it).path<<"\n"; std::string command = "umount "; command += (*it).path; @@ -301,6 +310,7 @@ bool RemovableDriveManager::update(long time) } search_for_drives(); check_and_notify(); + eject_drive(m_current_drives.back().path); return !m_current_drives.empty(); } From 7ca39aec5ec8c28484d5803cbd235a655a463aa4 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 4 Dec 2019 13:13:18 +0100 Subject: [PATCH 015/123] path check --- src/slic3r/GUI/RemovableDriveManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index e1ab1626c5c..3ff5735f911 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -255,6 +255,7 @@ void RemovableDriveManager::eject_drive(const std::string &path) if(correct_path[i]==' ') { correct_path = correct_path.insert(i,"\\"); + i++; } } std::cout<<"Ejecting "<<(*it).name<<" from "<< (*it).path<<"\n"; From e2764da71a0a1e6abf3fac389c33edeb90ce3644 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 4 Dec 2019 13:18:08 +0100 Subject: [PATCH 016/123] path check --- src/slic3r/GUI/RemovableDriveManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 3ff5735f911..7216763eec1 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -254,13 +254,13 @@ void RemovableDriveManager::eject_drive(const std::string &path) { if(correct_path[i]==' ') { - correct_path = correct_path.insert(i,"\\"); + correct_path = correct_path.insert(i,1,'\\'); i++; } } - std::cout<<"Ejecting "<<(*it).name<<" from "<< (*it).path<<"\n"; + std::cout<<"Ejecting "<<(*it).name<<" from "<< correct_path<"\n"; std::string command = "umount "; - command += (*it).path; + command += correct_path; int err = system(command.c_str()); if(err) { From 2dd495ca367fb274a7d582f4a45909eaf8629a0f Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 4 Dec 2019 13:21:41 +0100 Subject: [PATCH 017/123] path check --- src/slic3r/GUI/RemovableDriveManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 7216763eec1..c859a5d8723 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -258,7 +258,7 @@ void RemovableDriveManager::eject_drive(const std::string &path) i++; } } - std::cout<<"Ejecting "<<(*it).name<<" from "<< correct_path<"\n"; + std::cout<<"Ejecting "<<(*it).name<<" from "<< correct_path<<"\n"; std::string command = "umount "; command += correct_path; int err = system(command.c_str()); From 962f6bc64f09504bd648cb39f0f0eaa87d0e1577 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 4 Dec 2019 13:30:25 +0100 Subject: [PATCH 018/123] path check --- src/slic3r/GUI/RemovableDriveManager.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index c859a5d8723..3d77606c815 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -259,7 +259,13 @@ void RemovableDriveManager::eject_drive(const std::string &path) } } std::cout<<"Ejecting "<<(*it).name<<" from "<< correct_path<<"\n"; - std::string command = "umount "; + + std::string command = ""; +#if __APPLE__ + command = "diskutil unmount "; +#else + command = "umount "; +#endif command += correct_path; int err = system(command.c_str()); if(err) From 6e8bee05481f1797aaf2aa684600ccd267a30ba7 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 4 Dec 2019 13:43:28 +0100 Subject: [PATCH 019/123] comment testing lines --- src/slic3r/GUI/RemovableDriveManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 3d77606c815..0665e57dc2a 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -317,7 +317,7 @@ bool RemovableDriveManager::update(long time) } search_for_drives(); check_and_notify(); - eject_drive(m_current_drives.back().path); + //eject_drive(m_current_drives.back().path); return !m_current_drives.empty(); } From f8e7143dd20c8169731300a1cbe645d9846d3349 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 4 Dec 2019 15:27:33 +0100 Subject: [PATCH 020/123] refactoring --- src/slic3r/GUI/RemovableDriveManager.cpp | 14 +++++++------- src/slic3r/GUI/RemovableDriveManager.hpp | 3 ++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 0665e57dc2a..a655425fc4a 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -121,6 +121,7 @@ bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path) } void RemovableDriveManager::register_window() { + //std::cout << "Registering for device notification\n"; /* WNDCLASSEX wndClass; @@ -137,6 +138,7 @@ void RemovableDriveManager::register_window() wndClass.lpszMenuName = NULL; wndClass.hIconSm = wndClass.hIcon; */ + //std::cout << "Failed\n"; } #else void RemovableDriveManager::search_for_drives() @@ -191,7 +193,7 @@ void RemovableDriveManager::search_for_drives() } - std::cout << "found drives:" < callback); void print(); private: - RemovableDriveManager():m_drives_count(0){} + RemovableDriveManager():m_drives_count(0),m_last_update(0){} void search_for_drives(); void check_and_notify(); std::vector m_current_drives; std::vector> m_callbacks; size_t m_drives_count; + long m_last_update; #if _WIN32 void register_window(); #else From 4474cc6ea6104a7fd42d40505f7b86cdfe0f9ebc Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 5 Dec 2019 14:07:02 +0100 Subject: [PATCH 021/123] last path functions --- src/slic3r/GUI/GUI_App.cpp | 3 +- src/slic3r/GUI/Plater.cpp | 2 + src/slic3r/GUI/RemovableDriveManager.cpp | 174 +++++++++++++++++++++-- src/slic3r/GUI/RemovableDriveManager.hpp | 12 +- 4 files changed, 173 insertions(+), 18 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index c36c2748dd9..37753a0dea8 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -270,7 +270,8 @@ bool GUI_App::on_init_inner() this->obj_manipul()->update_if_dirty(); - RemovableDriveManager::get_instance().update(wxGetLocalTime()); + //RemovableDriveManager::get_instance().update(wxGetLocalTime()); + std::cout << RemovableDriveManager::get_instance().is_last_drive_removed() << "\n"; // Preset updating & Configwizard are done after the above initializations, // and after MainFrame is created & shown. diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 5d967cb6c0b..d1ce50f41f4 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4575,9 +4575,11 @@ void Plater::export_gcode() fs::path path = into_path(dlg.GetPath()); wxGetApp().app_config->update_last_output_dir(path.parent_path().string()); output_path = std::move(path); + RemovableDriveManager::get_instance().set_last_save_path(output_path.string()); } if (! output_path.empty()) p->export_gcode(std::move(output_path), PrintHostJob()); + } void Plater::export_stl(bool extended, bool selection_only) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index a655425fc4a..146bebc1195 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -7,8 +7,11 @@ #include #include #include -DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, - 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED); + +//#include +//GUID WceusbshGUID = { 0x25dbce51, 0x6c8f, 0x4a72, +// 0x8a,0x6d,0xb5,0x4c,0x2b,0x4f,0xc8,0x35 }; + #else //linux includes #include @@ -26,6 +29,7 @@ namespace GUI { #if _WIN32 +//INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); void RemovableDriveManager::search_for_drives() { m_current_drives.clear(); @@ -84,7 +88,7 @@ void RemovableDriveManager::eject_drive(const std::string &path) { std::string mpath = "\\\\.\\" + path; mpath = mpath.substr(0, mpath.size() - 1); - std::cout << "Ejecting " << mpath << "\n"; + //std::cout << "Ejecting " << mpath << "\n"; HANDLE handle = CreateFileA(mpath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); if (handle == INVALID_HANDLE_VALUE) { @@ -119,10 +123,24 @@ bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path) } return false; } +std::string RemovableDriveManager::get_drive_from_path(const std::string& path) +{ + int letter = PathGetDriveNumberA(path.c_str()); + for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) + { + char drive = (*it).path[0]; + if (drive == ('A' + letter)) + return (*it).path; + } + return ""; +} void RemovableDriveManager::register_window() { - //std::cout << "Registering for device notification\n"; /* + std::cout << "Registering for device notification\n"; + + + WNDCLASSEX wndClass; wndClass.cbSize = sizeof(WNDCLASSEX); @@ -134,12 +152,109 @@ void RemovableDriveManager::register_window() wndClass.hIcon = LoadIcon(0, IDI_APPLICATION); wndClass.hbrBackground = CreateSolidBrush(RGB(192, 192, 192)); wndClass.hCursor = LoadCursor(0, IDC_ARROW); - wndClass.lpszClassName = L"SlicerWindowClass"; + wndClass.lpszClassName = L"PrusaSlicer_aux_class"; wndClass.lpszMenuName = NULL; wndClass.hIconSm = wndClass.hIcon; - */ - //std::cout << "Failed\n"; + + HINSTANCE hInstanceExe = GetModuleHandle(NULL); + + HWND hWnd = CreateWindowEx( + WS_EX_CLIENTEDGE | WS_EX_APPWINDOW, + L"PrusaSlicer_aux_class", + L"PrusaSlicer_aux_wnd", + WS_OVERLAPPEDWINDOW, // style + CW_USEDEFAULT, 0, + 640, 480, + NULL, NULL, + hInstanceExe, + NULL); +*/ } +/* +INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + LRESULT lRet = 1; + static HDEVNOTIFY hDeviceNotify; + static HWND hEditWnd; + static ULONGLONG msgCount = 0; + + switch (message) + { + case WM_CREATE: + + + DEV_BROADCAST_DEVICEINTERFACE NotificationFilter; + + ZeroMemory(&NotificationFilter, sizeof(NotificationFilter)); + NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); + NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; + NotificationFilter.dbcc_classguid = WceusbshGUID; + + hDeviceNotify = RegisterDeviceNotification( + hWnd, // events recipient + &NotificationFilter, // type of device + DEVICE_NOTIFY_WINDOW_HANDLE // type of recipient handle + ); + break; + + + + case WM_DEVICECHANGE: + { + std::cout << "WM_DEVICECHANGE\n"; + /* + // This is the actual message from the interface via Windows messaging. + // This code includes some additional decoding for this particular device type + // and some common validation checks. + // + // Note that not all devices utilize these optional parameters in the same + // way. Refer to the extended information for your particular device type + // specified by your GUID. + // + PDEV_BROADCAST_DEVICEINTERFACE b = (PDEV_BROADCAST_DEVICEINTERFACE)lParam; + TCHAR strBuff[256]; + + // Output some messages to the window. + switch (wParam) + { + case DBT_DEVICEARRIVAL: + msgCount++; + StringCchPrintf( + strBuff, 256, + TEXT("Message %d: DBT_DEVICEARRIVAL\n"), msgCount); + break; + case DBT_DEVICEREMOVECOMPLETE: + msgCount++; + StringCchPrintf( + strBuff, 256, + TEXT("Message %d: DBT_DEVICEREMOVECOMPLETE\n"), msgCount); + break; + case DBT_DEVNODES_CHANGED: + msgCount++; + StringCchPrintf( + strBuff, 256, + TEXT("Message %d: DBT_DEVNODES_CHANGED\n"), msgCount); + break; + default: + msgCount++; + StringCchPrintf( + strBuff, 256, + TEXT("Message %d: WM_DEVICECHANGE message received, value %d unhandled.\n"), + msgCount, wParam); + break; + } + OutputMessage(hEditWnd, wParam, (LPARAM)strBuff); + / + } + break; + default: + // Send all other messages on to the default windows handler. + lRet = DefWindowProc(hWnd, message, wParam, lParam); + break; + } + return lRet; +} +*/ #else void RemovableDriveManager::search_for_drives() { @@ -294,6 +409,16 @@ bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path) } return false; } +std::string RemovableDriveManager::get_drive_from_path(const std::string& path) +{ + //check if same filesystem + for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) + { + if (compare_filesystem_id(path, (*it).path)) + return (*it).path; + } + return ""; +} #endif bool RemovableDriveManager::update(long time) { @@ -301,7 +426,7 @@ bool RemovableDriveManager::update(long time) { //add_callback([](void) { RemovableDriveManager::get_instance().print(); }); #if _WIN32 - register_window(); + //register_window(); #endif } if(time != 0) //time = 0 is forced update @@ -338,11 +463,9 @@ std::string RemovableDriveManager::get_last_drive_path() { if (!m_current_drives.empty()) { -//#if _WIN32 -// return m_current_drives.back().path + "\\"; -//#else + if (m_last_save_path != "") + return m_last_save_path; return m_current_drives.back().path; -//#endif } return ""; } @@ -356,9 +479,12 @@ void RemovableDriveManager::check_and_notify() if(m_drives_count != m_current_drives.size()) { //std::cout<<" vs "<< m_current_drives.size(); - for (auto it = m_callbacks.begin(); it != m_callbacks.end(); ++it) + if(m_drives_count > m_current_drives.size()) { - (*it)(); + for (auto it = m_callbacks.begin(); it != m_callbacks.end(); ++it) + { + (*it)(); + } } m_drives_count = m_current_drives.size(); } @@ -368,6 +494,26 @@ void RemovableDriveManager::add_callback(std::function callback) { m_callbacks.push_back(callback); } +void RemovableDriveManager::set_last_save_path(const std::string& path) +{ + std::string last_drive = get_drive_from_path(path); + if(last_drive != "") + { + m_last_save_path = last_drive; + } +} +bool RemovableDriveManager::is_last_drive_removed() +{ + if(m_last_save_path == "") + { + return true; + } + return !is_drive_mounted(m_last_save_path); +} +void RemovableDriveManager::reset_last_save_path() +{ + m_last_save_path = ""; +} void RemovableDriveManager::print() { std::cout << "notified\n"; diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index c65a7fe6252..be5ae5968e5 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -24,24 +24,30 @@ public: void operator=(RemovableDriveManager const&) = delete; //update() searches for removable devices, returns false if empty. - bool update(long time = 0); //time = 0 is forced update + bool update(long time = 0); //time = 0 is forced update, time expects wxGetLocalTime() bool is_drive_mounted(const std::string &path); void eject_drive(const std::string &path); std::string get_last_drive_path(); std::vector get_all_drives(); bool is_path_on_removable_drive(const std::string &path); - void add_callback(std::function callback); + void add_callback(std::function callback); // callback will notify every drive removal. to see if it was last used drive call is_last_drive_removed() + void set_last_save_path(const std::string &path); + bool is_last_drive_removed(); //if we dont need info about this drive, call reset_last_save_path(); + void reset_last_save_path(); void print(); private: - RemovableDriveManager():m_drives_count(0),m_last_update(0){} + RemovableDriveManager():m_drives_count(0),m_last_update(0),m_last_save_path(""){} void search_for_drives(); void check_and_notify(); + std::string get_drive_from_path(const std::string& path);//returns drive path (same as path in DriveData) if exists otherwise empty string "" std::vector m_current_drives; std::vector> m_callbacks; size_t m_drives_count; long m_last_update; + std::string m_last_save_path; #if _WIN32 void register_window(); + //INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); #else void search_path(const std::string &path, const std::string &parent_path); bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); From 30671c56abbb87ffa8840fc77c54b1c73c11bf78 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 5 Dec 2019 16:22:54 +0100 Subject: [PATCH 022/123] last save path --- src/slic3r/GUI/GUI_App.cpp | 7 ++++--- src/slic3r/GUI/RemovableDriveManager.cpp | 10 ++++++++-- src/slic3r/GUI/RemovableDriveManager.hpp | 3 ++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 37753a0dea8..ed5371e669e 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -270,9 +270,10 @@ bool GUI_App::on_init_inner() this->obj_manipul()->update_if_dirty(); - //RemovableDriveManager::get_instance().update(wxGetLocalTime()); - std::cout << RemovableDriveManager::get_instance().is_last_drive_removed() << "\n"; - + + RemovableDriveManager::get_instance().update(wxGetLocalTime()); + + // Preset updating & Configwizard are done after the above initializations, // and after MainFrame is created & shown. // The extra CallAfter() is needed because of Mac, where this is the only way diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 146bebc1195..e94ea6918ad 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -420,11 +420,11 @@ std::string RemovableDriveManager::get_drive_from_path(const std::string& path) return ""; } #endif -bool RemovableDriveManager::update(long time) +bool RemovableDriveManager::update(const long time) { if(m_last_update == 0) { - //add_callback([](void) { RemovableDriveManager::get_instance().print(); }); + add_callback([](void) { RemovableDriveManager::get_instance().print(); }); #if _WIN32 //register_window(); #endif @@ -510,12 +510,18 @@ bool RemovableDriveManager::is_last_drive_removed() } return !is_drive_mounted(m_last_save_path); } +bool RemovableDriveManager::is_last_drive_removed_with_update(const long time) +{ + update(time); + return is_last_drive_removed(); +} void RemovableDriveManager::reset_last_save_path() { m_last_save_path = ""; } void RemovableDriveManager::print() { + //std::cout << "Removed Device: "<<(int)is_last_drive_removed()<<"\n"; std::cout << "notified\n"; } }}//namespace Slicer::Gui:: \ No newline at end of file diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index be5ae5968e5..906667244be 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -24,7 +24,7 @@ public: void operator=(RemovableDriveManager const&) = delete; //update() searches for removable devices, returns false if empty. - bool update(long time = 0); //time = 0 is forced update, time expects wxGetLocalTime() + bool update(const long time = 0); //time = 0 is forced update, time expects wxGetLocalTime() bool is_drive_mounted(const std::string &path); void eject_drive(const std::string &path); std::string get_last_drive_path(); @@ -33,6 +33,7 @@ public: void add_callback(std::function callback); // callback will notify every drive removal. to see if it was last used drive call is_last_drive_removed() void set_last_save_path(const std::string &path); bool is_last_drive_removed(); //if we dont need info about this drive, call reset_last_save_path(); + bool is_last_drive_removed_with_update(const long time = 0); // param as update() void reset_last_save_path(); void print(); private: From cfa0a3fd4f92f6c1325f91429ad1b68a878beda5 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Fri, 6 Dec 2019 13:17:36 +0100 Subject: [PATCH 023/123] callback only for used device --- src/slic3r/GUI/RemovableDriveManager.cpp | 2 +- src/slic3r/GUI/RemovableDriveManager.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index e94ea6918ad..6581d536141 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -479,7 +479,7 @@ void RemovableDriveManager::check_and_notify() if(m_drives_count != m_current_drives.size()) { //std::cout<<" vs "<< m_current_drives.size(); - if(m_drives_count > m_current_drives.size()) + if(m_drives_count > m_current_drives.size() && m_last_save_path != "" && !is_drive_mounted(m_last_save_path)) { for (auto it = m_callbacks.begin(); it != m_callbacks.end(); ++it) { diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 906667244be..741b4424ab1 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -30,7 +30,7 @@ public: std::string get_last_drive_path(); std::vector get_all_drives(); bool is_path_on_removable_drive(const std::string &path); - void add_callback(std::function callback); // callback will notify every drive removal. to see if it was last used drive call is_last_drive_removed() + void add_callback(std::function callback); // callback will notify only if device with last save path was removed void set_last_save_path(const std::string &path); bool is_last_drive_removed(); //if we dont need info about this drive, call reset_last_save_path(); bool is_last_drive_removed_with_update(const long time = 0); // param as update() From 97d23ff0aaa5a9b7fcd2c2af5ba2baa41b07ec21 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Fri, 6 Dec 2019 13:21:44 +0100 Subject: [PATCH 024/123] erase callbacks --- src/slic3r/GUI/RemovableDriveManager.cpp | 4 ++++ src/slic3r/GUI/RemovableDriveManager.hpp | 1 + 2 files changed, 5 insertions(+) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 6581d536141..1fbc33fc579 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -494,6 +494,10 @@ void RemovableDriveManager::add_callback(std::function callback) { m_callbacks.push_back(callback); } +void RemovableDriveManager::erase_callbacks() +{ + m_callbacks.clear(); +} void RemovableDriveManager::set_last_save_path(const std::string& path) { std::string last_drive = get_drive_from_path(path); diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 741b4424ab1..8d9e65c47ec 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -31,6 +31,7 @@ public: std::vector get_all_drives(); bool is_path_on_removable_drive(const std::string &path); void add_callback(std::function callback); // callback will notify only if device with last save path was removed + void erase_callbacks(); // erases all callbacks added by add_callback() void set_last_save_path(const std::string &path); bool is_last_drive_removed(); //if we dont need info about this drive, call reset_last_save_path(); bool is_last_drive_removed_with_update(const long time = 0); // param as update() From 78f779cfc1b72e8f9d13f92b080dd2b58b4c36c9 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Fri, 6 Dec 2019 16:51:04 +0100 Subject: [PATCH 025/123] windows registration for device notif(thru hidden app) - windows doesnt need update now --- src/slic3r/GUI/GUI_App.cpp | 3 +- src/slic3r/GUI/RemovableDriveManager.cpp | 108 ++++++++--------------- src/slic3r/GUI/RemovableDriveManager.hpp | 2 + 3 files changed, 40 insertions(+), 73 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index ed5371e669e..90e6cd4bdb3 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -271,7 +271,7 @@ bool GUI_App::on_init_inner() this->obj_manipul()->update_if_dirty(); - RemovableDriveManager::get_instance().update(wxGetLocalTime()); + //RemovableDriveManager::get_instance().update(wxGetLocalTime()); // Preset updating & Configwizard are done after the above initializations, @@ -301,6 +301,7 @@ bool GUI_App::on_init_inner() preset_updater->slic3r_update_notify(); preset_updater->sync(preset_bundle); }); + RemovableDriveManager::get_instance().init(); } }); diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 1fbc33fc579..5daa9eb261e 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -8,9 +8,9 @@ #include #include -//#include -//GUID WceusbshGUID = { 0x25dbce51, 0x6c8f, 0x4a72, -// 0x8a,0x6d,0xb5,0x4c,0x2b,0x4f,0xc8,0x35 }; +#include +GUID WceusbshGUID = { 0x25dbce51, 0x6c8f, 0x4a72, + 0x8a,0x6d,0xb5,0x4c,0x2b,0x4f,0xc8,0x35 }; #else //linux includes @@ -29,7 +29,7 @@ namespace GUI { #if _WIN32 -//INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); +INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); void RemovableDriveManager::search_for_drives() { m_current_drives.clear(); @@ -136,13 +136,8 @@ std::string RemovableDriveManager::get_drive_from_path(const std::string& path) } void RemovableDriveManager::register_window() { - /* std::cout << "Registering for device notification\n"; - - - WNDCLASSEX wndClass; - wndClass.cbSize = sizeof(WNDCLASSEX); wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wndClass.hInstance = reinterpret_cast(GetModuleHandle(0)); @@ -155,34 +150,41 @@ void RemovableDriveManager::register_window() wndClass.lpszClassName = L"PrusaSlicer_aux_class"; wndClass.lpszMenuName = NULL; wndClass.hIconSm = wndClass.hIcon; - - HINSTANCE hInstanceExe = GetModuleHandle(NULL); + if(!RegisterClassEx(&wndClass)) + { + DWORD err = GetLastError(); + return; + } HWND hWnd = CreateWindowEx( - WS_EX_CLIENTEDGE | WS_EX_APPWINDOW, + WS_EX_NOACTIVATE, L"PrusaSlicer_aux_class", L"PrusaSlicer_aux_wnd", - WS_OVERLAPPEDWINDOW, // style + WS_DISABLED, // style CW_USEDEFAULT, 0, 640, 480, NULL, NULL, - hInstanceExe, + GetModuleHandle(NULL), NULL); -*/ + if(hWnd == NULL) + { + DWORD err = GetLastError(); + } + //ShowWindow(hWnd, SW_SHOWNORMAL); + UpdateWindow(hWnd); } -/* + INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { LRESULT lRet = 1; static HDEVNOTIFY hDeviceNotify; + static HWND hEditWnd; static ULONGLONG msgCount = 0; switch (message) { case WM_CREATE: - - DEV_BROADCAST_DEVICEINTERFACE NotificationFilter; ZeroMemory(&NotificationFilter, sizeof(NotificationFilter)); @@ -196,55 +198,13 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP DEVICE_NOTIFY_WINDOW_HANDLE // type of recipient handle ); break; - - - case WM_DEVICECHANGE: { - std::cout << "WM_DEVICECHANGE\n"; - /* - // This is the actual message from the interface via Windows messaging. - // This code includes some additional decoding for this particular device type - // and some common validation checks. - // - // Note that not all devices utilize these optional parameters in the same - // way. Refer to the extended information for your particular device type - // specified by your GUID. - // - PDEV_BROADCAST_DEVICEINTERFACE b = (PDEV_BROADCAST_DEVICEINTERFACE)lParam; - TCHAR strBuff[256]; - - // Output some messages to the window. - switch (wParam) + if(wParam == DBT_DEVICEREMOVECOMPLETE) { - case DBT_DEVICEARRIVAL: - msgCount++; - StringCchPrintf( - strBuff, 256, - TEXT("Message %d: DBT_DEVICEARRIVAL\n"), msgCount); - break; - case DBT_DEVICEREMOVECOMPLETE: - msgCount++; - StringCchPrintf( - strBuff, 256, - TEXT("Message %d: DBT_DEVICEREMOVECOMPLETE\n"), msgCount); - break; - case DBT_DEVNODES_CHANGED: - msgCount++; - StringCchPrintf( - strBuff, 256, - TEXT("Message %d: DBT_DEVNODES_CHANGED\n"), msgCount); - break; - default: - msgCount++; - StringCchPrintf( - strBuff, 256, - TEXT("Message %d: WM_DEVICECHANGE message received, value %d unhandled.\n"), - msgCount, wParam); - break; + std::cout << "WM_DEVICECHANGE\n"; + RemovableDriveManager::get_instance().on_drive_removed_callback(); } - OutputMessage(hEditWnd, wParam, (LPARAM)strBuff); - / } break; default: @@ -254,7 +214,7 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP } return lRet; } -*/ + #else void RemovableDriveManager::search_for_drives() { @@ -420,15 +380,16 @@ std::string RemovableDriveManager::get_drive_from_path(const std::string& path) return ""; } #endif +void RemovableDriveManager::init() +{ + add_callback([](void) { RemovableDriveManager::get_instance().print(); }); +#if _WIN32 + register_window(); +#endif + update(); +} bool RemovableDriveManager::update(const long time) { - if(m_last_update == 0) - { - add_callback([](void) { RemovableDriveManager::get_instance().print(); }); -#if _WIN32 - //register_window(); -#endif - } if(time != 0) //time = 0 is forced update { long diff = m_last_update - time; @@ -442,7 +403,6 @@ bool RemovableDriveManager::update(const long time) } search_for_drives(); check_and_notify(); - //eject_drive(m_current_drives.back().path); return !m_current_drives.empty(); } @@ -523,6 +483,10 @@ void RemovableDriveManager::reset_last_save_path() { m_last_save_path = ""; } +void RemovableDriveManager::on_drive_removed_callback() +{ + update(); +} void RemovableDriveManager::print() { //std::cout << "Removed Device: "<<(int)is_last_drive_removed()<<"\n"; diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 8d9e65c47ec..210d89477b2 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -24,6 +24,7 @@ public: void operator=(RemovableDriveManager const&) = delete; //update() searches for removable devices, returns false if empty. + void init(); bool update(const long time = 0); //time = 0 is forced update, time expects wxGetLocalTime() bool is_drive_mounted(const std::string &path); void eject_drive(const std::string &path); @@ -36,6 +37,7 @@ public: bool is_last_drive_removed(); //if we dont need info about this drive, call reset_last_save_path(); bool is_last_drive_removed_with_update(const long time = 0); // param as update() void reset_last_save_path(); + void on_drive_removed_callback(); void print(); private: RemovableDriveManager():m_drives_count(0),m_last_update(0),m_last_save_path(""){} From ef58a65e013dcf7dc4d85a855ab26bc413e26635 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 9 Dec 2019 15:33:10 +0100 Subject: [PATCH 026/123] osx device unmount callback - not sure if will build --- src/slic3r/CMakeLists.txt | 1 + src/slic3r/GUI/RemovableDriveManager.cpp | 11 ++--- src/slic3r/GUI/RemovableDriveManager.hpp | 4 +- src/slic3r/GUI/RemovableDriveManager.mm | 51 ++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 src/slic3r/GUI/RemovableDriveManager.mm diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 03413f93379..6a14a1b3f36 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -169,6 +169,7 @@ if (APPLE) list(APPEND SLIC3R_GUI_SOURCES Utils/RetinaHelperImpl.mm Utils/MacDarkMode.mm + GUI/RemovableDriveManager.mm ) endif () diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 5daa9eb261e..166728e68ba 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -203,7 +203,7 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP if(wParam == DBT_DEVICEREMOVECOMPLETE) { std::cout << "WM_DEVICECHANGE\n"; - RemovableDriveManager::get_instance().on_drive_removed_callback(); + RemovableDriveManager::get_instance().update(); } } break; @@ -219,6 +219,10 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP void RemovableDriveManager::search_for_drives() { +#if __APPLE__ + list_devices(); +#endif + m_current_drives.clear(); m_current_drives.reserve(26); @@ -483,10 +487,7 @@ void RemovableDriveManager::reset_last_save_path() { m_last_save_path = ""; } -void RemovableDriveManager::on_drive_removed_callback() -{ - update(); -} + void RemovableDriveManager::print() { //std::cout << "Removed Device: "<<(int)is_last_drive_removed()<<"\n"; diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 210d89477b2..501c16b71ad 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -37,7 +37,6 @@ public: bool is_last_drive_removed(); //if we dont need info about this drive, call reset_last_save_path(); bool is_last_drive_removed_with_update(const long time = 0); // param as update() void reset_last_save_path(); - void on_drive_removed_callback(); void print(); private: RemovableDriveManager():m_drives_count(0),m_last_update(0),m_last_save_path(""){} @@ -52,6 +51,9 @@ private: #if _WIN32 void register_window(); //INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); +#elif __APPLE__ + void register_window(); + void list_devices(); #else void search_path(const std::string &path, const std::string &parent_path); bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); diff --git a/src/slic3r/GUI/RemovableDriveManager.mm b/src/slic3r/GUI/RemovableDriveManager.mm new file mode 100644 index 00000000000..a1358625fc0 --- /dev/null +++ b/src/slic3r/GUI/RemovableDriveManager.mm @@ -0,0 +1,51 @@ +#import "RemovableDriveManager.hpp" + +@implementation RemovableDriveManager + +namespace Slic3r { +namespace GUI { + +void RemovableDriveManager::register_window() +{ + //[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(volumesChanged:) name:NSWorkspaceDidMountNotification object: nil]; + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(on_device_unmount:) name:NSWorkspaceDidUnmountNotification object:nil]; +} + +-(void) on_device_unmount: (NSNotification*) notification +{ + NSLog(@"on device change"); + RemovableDriveManager::get_instance().update(); +} + +-(void) RemovableDriveManager::list_devices() +{ + NSLog(@"---"); + NSArray* devices = [[NSWorkspace sharedWorkspace] mountedRemovableMedia]; + for (NSString* volumePath in listOfMedia) + { + NSLog(@"@", volumePath); + } + NSLog(@"--"); + //removable here means CD not USB :/ + NSArray* listOfMedia = [[NSWorkspace sharedWorkspace] mountedLocalVolumePaths]; + NSLog(@"%@", listOfMedia); + + for (NSString* volumePath in listOfMedia) + { + BOOL isRemovable = NO; + BOOL isWritable = NO; + BOOL isUnmountable = NO; + NSString* description = [NSString string]; + NSString* type = [NSString string]; + + BOOL result = [[NSWorkspace sharedWorkspace] getFileSystemInfoForPath:volumePath + isRemovable:&isRemovable + isWritable:&isWritable + isUnmountable:&isUnmountable + description:&description + type:&type]; + NSLog(@"Result:%i Volume: %@, Removable:%i, W:%i, Unmountable:%i, Desc:%@, type:%@", result, volumePath, isRemovable, isWritable, isUnmountable, description, type); + } +} + +}}//namespace Slicer::GUI \ No newline at end of file From 8af91fed870633deb7c6fa680d2381f4f1baf635 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 9 Dec 2019 17:12:22 +0100 Subject: [PATCH 027/123] init call --- src/slic3r/GUI/GUI_App.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 90e6cd4bdb3..1b2fe919a22 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -260,6 +260,8 @@ bool GUI_App::on_init_inner() m_printhost_job_queue.reset(new PrintHostJobQueue(mainframe->printhost_queue_dlg())); + RemovableDriveManager::get_instance().init(); + Bind(wxEVT_IDLE, [this](wxIdleEvent& event) { if (! plater_) @@ -301,7 +303,7 @@ bool GUI_App::on_init_inner() preset_updater->slic3r_update_notify(); preset_updater->sync(preset_bundle); }); - RemovableDriveManager::get_instance().init(); + } }); From 2c17ec843bc5d7f0f4cf7a675a7f0c6050ef35e9 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 10 Dec 2019 10:08:57 +0100 Subject: [PATCH 028/123] macos mm files --- src/slic3r/CMakeLists.txt | 3 +- src/slic3r/GUI/RemovableDriveManager.hpp | 3 +- src/slic3r/GUI/RemovableDriveManagerMM.h | 9 ++++++ ...eManager.mm => RemovableDriveManagerMM.mm} | 29 +++++++++++++++---- 4 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 src/slic3r/GUI/RemovableDriveManagerMM.h rename src/slic3r/GUI/{RemovableDriveManager.mm => RemovableDriveManagerMM.mm} (86%) diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 6a14a1b3f36..9d51f6219ce 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -169,7 +169,8 @@ if (APPLE) list(APPEND SLIC3R_GUI_SOURCES Utils/RetinaHelperImpl.mm Utils/MacDarkMode.mm - GUI/RemovableDriveManager.mm + GUI/RemovableDriveManagerMM.mm + GUI/RemovableDriveManagerMM.h ) endif () diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 501c16b71ad..04bbe48b5d0 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -52,8 +52,9 @@ private: void register_window(); //INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); #elif __APPLE__ + void *m_rdmmm; void register_window(); - void list_devices(); + //void list_devices(); #else void search_path(const std::string &path, const std::string &parent_path); bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.h b/src/slic3r/GUI/RemovableDriveManagerMM.h new file mode 100644 index 00000000000..8f783c2d2a9 --- /dev/null +++ b/src/slic3r/GUI/RemovableDriveManagerMM.h @@ -0,0 +1,9 @@ +#import + +@interface RemovableDriveManagerMM : NSObject + +-(instancetype) init; +-(void) add_unmount_observer; +-(void) on_device_unmount: (NSNotification*) notification; + +@end \ No newline at end of file diff --git a/src/slic3r/GUI/RemovableDriveManager.mm b/src/slic3r/GUI/RemovableDriveManagerMM.mm similarity index 86% rename from src/slic3r/GUI/RemovableDriveManager.mm rename to src/slic3r/GUI/RemovableDriveManagerMM.mm index a1358625fc0..e4e324654ec 100644 --- a/src/slic3r/GUI/RemovableDriveManager.mm +++ b/src/slic3r/GUI/RemovableDriveManagerMM.mm @@ -1,22 +1,39 @@ #import "RemovableDriveManager.hpp" -@implementation RemovableDriveManager +#import + +@implementation RemovableDriveManagerMM namespace Slic3r { namespace GUI { -void RemovableDriveManager::register_window() +-(instancetype) init { - //[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(volumesChanged:) name:NSWorkspaceDidMountNotification object: nil]; - [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(on_device_unmount:) name:NSWorkspaceDidUnmountNotification object:nil]; + self = [super init]; + if(self) + { + [self add_unmount_observer] + } + return self; } - -(void) on_device_unmount: (NSNotification*) notification { NSLog(@"on device change"); RemovableDriveManager::get_instance().update(); } +-(void) add_unmount_observer +{ + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(on_device_unmount:) name:NSWorkspaceDidUnmountNotification object:nil]; +} +void RemovableDriveManager::register_window() +{ + m_rdmmm = nullptr; + m_rdmmm = [[RemovableDriveManagerMM alloc] init]; +} + + +/* -(void) RemovableDriveManager::list_devices() { NSLog(@"---"); @@ -47,5 +64,5 @@ void RemovableDriveManager::register_window() NSLog(@"Result:%i Volume: %@, Removable:%i, W:%i, Unmountable:%i, Desc:%@, type:%@", result, volumePath, isRemovable, isWritable, isUnmountable, description, type); } } - +*/ }}//namespace Slicer::GUI \ No newline at end of file From f0b4973a08ba7ace1d8697af938a5965fb4ed162 Mon Sep 17 00:00:00 2001 From: Slic3rPE Date: Tue, 10 Dec 2019 11:17:12 +0100 Subject: [PATCH 029/123] macos implementation --- src/slic3r/GUI/RemovableDriveManager.cpp | 8 +++++--- src/slic3r/GUI/RemovableDriveManager.hpp | 4 +++- src/slic3r/GUI/RemovableDriveManagerMM.mm | 18 ++++++++++-------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 166728e68ba..8145c90760b 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -218,11 +218,11 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP #else void RemovableDriveManager::search_for_drives() { - + /* #if __APPLE__ list_devices(); #endif - +*/ m_current_drives.clear(); m_current_drives.reserve(26); @@ -389,6 +389,8 @@ void RemovableDriveManager::init() add_callback([](void) { RemovableDriveManager::get_instance().print(); }); #if _WIN32 register_window(); +#elif __APPLE__ + register_window(); #endif update(); } @@ -493,4 +495,4 @@ void RemovableDriveManager::print() //std::cout << "Removed Device: "<<(int)is_last_drive_removed()<<"\n"; std::cout << "notified\n"; } -}}//namespace Slicer::Gui:: \ No newline at end of file +}}//namespace Slicer::Gui:: diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 04bbe48b5d0..c4f55029b75 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -55,10 +55,12 @@ private: void *m_rdmmm; void register_window(); //void list_devices(); + void search_path(const std::string &path, const std::string &parent_path); + bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); #else void search_path(const std::string &path, const std::string &parent_path); bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); #endif }; }} -#endif \ No newline at end of file +#endif diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.mm b/src/slic3r/GUI/RemovableDriveManagerMM.mm index e4e324654ec..99abd73860f 100644 --- a/src/slic3r/GUI/RemovableDriveManagerMM.mm +++ b/src/slic3r/GUI/RemovableDriveManagerMM.mm @@ -1,37 +1,38 @@ #import "RemovableDriveManager.hpp" - +#import "RemovableDriveManagerMM.h" #import @implementation RemovableDriveManagerMM -namespace Slic3r { -namespace GUI { + -(instancetype) init { self = [super init]; if(self) { - [self add_unmount_observer] + [self add_unmount_observer]; } return self; } -(void) on_device_unmount: (NSNotification*) notification { NSLog(@"on device change"); - RemovableDriveManager::get_instance().update(); + Slic3r::GUI::RemovableDriveManager::get_instance().update(); } -(void) add_unmount_observer { + NSLog(@"add unmount observer"); [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(on_device_unmount:) name:NSWorkspaceDidUnmountNotification object:nil]; } - +namespace Slic3r { +namespace GUI { void RemovableDriveManager::register_window() { m_rdmmm = nullptr; m_rdmmm = [[RemovableDriveManagerMM alloc] init]; } - +}}//namespace Slicer::GUI /* -(void) RemovableDriveManager::list_devices() @@ -65,4 +66,5 @@ void RemovableDriveManager::register_window() } } */ -}}//namespace Slicer::GUI \ No newline at end of file + +@end From 998dc7b6c6159bbc688d50360a29401c599c63e8 Mon Sep 17 00:00:00 2001 From: Slic3rPE Date: Tue, 10 Dec 2019 11:35:39 +0100 Subject: [PATCH 030/123] macos list devices --- src/slic3r/GUI/RemovableDriveManager.cpp | 4 +- src/slic3r/GUI/RemovableDriveManager.hpp | 4 +- src/slic3r/GUI/RemovableDriveManagerMM.h | 4 +- src/slic3r/GUI/RemovableDriveManagerMM.mm | 65 +++++++++++++---------- 4 files changed, 42 insertions(+), 35 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 8145c90760b..50e2b6359c4 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -218,11 +218,11 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP #else void RemovableDriveManager::search_for_drives() { - /* + #if __APPLE__ list_devices(); #endif -*/ + m_current_drives.clear(); m_current_drives.reserve(26); diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index c4f55029b75..7109bbd0708 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -39,7 +39,7 @@ public: void reset_last_save_path(); void print(); private: - RemovableDriveManager():m_drives_count(0),m_last_update(0),m_last_save_path(""){} + RemovableDriveManager():m_drives_count(0),m_last_update(0),m_last_save_path(""),m_rdmmm(nullptr){} void search_for_drives(); void check_and_notify(); std::string get_drive_from_path(const std::string& path);//returns drive path (same as path in DriveData) if exists otherwise empty string "" @@ -54,7 +54,7 @@ private: #elif __APPLE__ void *m_rdmmm; void register_window(); - //void list_devices(); + void list_devices(); void search_path(const std::string &path, const std::string &parent_path); bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); #else diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.h b/src/slic3r/GUI/RemovableDriveManagerMM.h index 8f783c2d2a9..4a5fa2515ed 100644 --- a/src/slic3r/GUI/RemovableDriveManagerMM.h +++ b/src/slic3r/GUI/RemovableDriveManagerMM.h @@ -5,5 +5,5 @@ -(instancetype) init; -(void) add_unmount_observer; -(void) on_device_unmount: (NSNotification*) notification; - -@end \ No newline at end of file +-(void) list_dev; +@end diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.mm b/src/slic3r/GUI/RemovableDriveManagerMM.mm index 99abd73860f..7e8b56c59b0 100644 --- a/src/slic3r/GUI/RemovableDriveManagerMM.mm +++ b/src/slic3r/GUI/RemovableDriveManagerMM.mm @@ -25,6 +25,36 @@ NSLog(@"add unmount observer"); [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(on_device_unmount:) name:NSWorkspaceDidUnmountNotification object:nil]; } +-(void) list_dev +{ + NSLog(@"---"); + NSArray* devices = [[NSWorkspace sharedWorkspace] mountedRemovableMedia]; + for (NSString* volumePath in devices) + { + NSLog(@"@", volumePath); + } + NSLog(@"--"); + //removable here means CD not USB :/ + NSArray* listOfMedia = [[NSWorkspace sharedWorkspace] mountedLocalVolumePaths]; + NSLog(@"%@", listOfMedia); + + for (NSString* volumePath in listOfMedia) + { + BOOL isRemovable = NO; + BOOL isWritable = NO; + BOOL isUnmountable = NO; + NSString* description = [NSString string]; + NSString* type = [NSString string]; + + BOOL result = [[NSWorkspace sharedWorkspace] getFileSystemInfoForPath:volumePath + isRemovable:&isRemovable + isWritable:&isWritable + isUnmountable:&isUnmountable + description:&description + type:&type]; + NSLog(@"Result:%i Volume: %@, Removable:%i, W:%i, Unmountable:%i, Desc:%@, type:%@", result, volumePath, isRemovable, isWritable, isUnmountable, description, type); + } +} namespace Slic3r { namespace GUI { void RemovableDriveManager::register_window() @@ -32,39 +62,16 @@ void RemovableDriveManager::register_window() m_rdmmm = nullptr; m_rdmmm = [[RemovableDriveManagerMM alloc] init]; } +void RemovableDriveManager::list_devices() +{ + if(m_rdmmm == nullptr) + return; + [m_rdmmm list_dev]; +} }}//namespace Slicer::GUI /* --(void) RemovableDriveManager::list_devices() -{ - NSLog(@"---"); - NSArray* devices = [[NSWorkspace sharedWorkspace] mountedRemovableMedia]; - for (NSString* volumePath in listOfMedia) - { - NSLog(@"@", volumePath); - } - NSLog(@"--"); - //removable here means CD not USB :/ - NSArray* listOfMedia = [[NSWorkspace sharedWorkspace] mountedLocalVolumePaths]; - NSLog(@"%@", listOfMedia); - for (NSString* volumePath in listOfMedia) - { - BOOL isRemovable = NO; - BOOL isWritable = NO; - BOOL isUnmountable = NO; - NSString* description = [NSString string]; - NSString* type = [NSString string]; - - BOOL result = [[NSWorkspace sharedWorkspace] getFileSystemInfoForPath:volumePath - isRemovable:&isRemovable - isWritable:&isWritable - isUnmountable:&isUnmountable - description:&description - type:&type]; - NSLog(@"Result:%i Volume: %@, Removable:%i, W:%i, Unmountable:%i, Desc:%@, type:%@", result, volumePath, isRemovable, isWritable, isUnmountable, description, type); - } -} */ @end From 212583b52ec9b0e89f32438b9fe823a3bb00f3f0 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 10 Dec 2019 14:10:47 +0100 Subject: [PATCH 031/123] macos better wrapper --- src/slic3r/GUI/RemovableDriveManager.cpp | 50 +++++++++-------- src/slic3r/GUI/RemovableDriveManager.hpp | 33 ++++++++--- src/slic3r/GUI/RemovableDriveManagerMM.h | 2 +- src/slic3r/GUI/RemovableDriveManagerMM.mm | 68 +++++++++++------------ 4 files changed, 87 insertions(+), 66 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 50e2b6359c4..763113ea2cf 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -220,9 +220,11 @@ void RemovableDriveManager::search_for_drives() { #if __APPLE__ - list_devices(); -#endif - + if(m_rdmmm) + { + m_rdmmm->list_devices(); + } +#else m_current_drives.clear(); m_current_drives.reserve(26); @@ -273,6 +275,7 @@ void RemovableDriveManager::search_for_drives() } //std::cout << "found drives:" <pw_name == username) - { - std::string name = basename(globbuf.gl_pathv[i]); - m_current_drives.push_back(DriveData(name,globbuf.gl_pathv[i])); - } - } - } + } }else { @@ -310,7 +296,27 @@ void RemovableDriveManager::search_path(const std::string &path,const std::strin globfree(&globbuf); } - +void RemovableDriveManager::inspect_file(const std::string &path, const std::string &parent_path) +{ + //if not same file system - could be removable drive + if(!compare_filesystem_id(globbuf.gl_pathv[i], parent_path)) + { + //user id + struct stat buf; + stat(globbuf.gl_pathv[i],&buf); + uid_t uid = buf.st_uid; + std::string username(std::getenv("USER")); + struct passwd *pw = getpwuid(uid); + if(pw != 0) + { + if(pw->pw_name == username) + { + std::string name = basename(globbuf.gl_pathv[i]); + m_current_drives.push_back(DriveData(name,globbuf.gl_pathv[i])); + } + } + } +} bool RemovableDriveManager::compare_filesystem_id(const std::string &path_a, const std::string &path_b) { struct stat buf; diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 7109bbd0708..202680328eb 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -39,7 +39,11 @@ public: void reset_last_save_path(); void print(); private: - RemovableDriveManager():m_drives_count(0),m_last_update(0),m_last_save_path(""),m_rdmmm(nullptr){} +#if __APPLE__ + RemovableDriveManager():m_drives_count(0),m_last_update(0),m_last_save_path(""),m_rdmmm(new RemovableDriveManagerMM()){} +#else + RemovableDriveManager() : m_drives_count(0), m_last_update(0), m_last_save_path(""){} +#endif void search_for_drives(); void check_and_notify(); std::string get_drive_from_path(const std::string& path);//returns drive path (same as path in DriveData) if exists otherwise empty string "" @@ -51,16 +55,27 @@ private: #if _WIN32 void register_window(); //INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); -#elif __APPLE__ - void *m_rdmmm; - void register_window(); - void list_devices(); - void search_path(const std::string &path, const std::string &parent_path); - bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); #else - void search_path(const std::string &path, const std::string &parent_path); - bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); +#if __APPLE__ + RemovableDriveManagerMM * m_rdmmm; + #endif + void search_path(const std::string &path, const std::string &parent_path); + void inspect_file(const std::string &path, const std::string &parent_path); + bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); #endif }; +#if __APPLE__ +class RemovableDriveManagerMM +{ +public: + RemovableDriveManagerMM(); + ~RemovableDriveManagerMM(); + register_window(); + list_devices(); +private: + RemovableDriveManagerMMImpl *m_imp; + friend void RemovableDriveManager::inspect_file(const std::string &path, const std::string &parent_path); +}; +#endif }} #endif diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.h b/src/slic3r/GUI/RemovableDriveManagerMM.h index 4a5fa2515ed..29994154546 100644 --- a/src/slic3r/GUI/RemovableDriveManagerMM.h +++ b/src/slic3r/GUI/RemovableDriveManagerMM.h @@ -5,5 +5,5 @@ -(instancetype) init; -(void) add_unmount_observer; -(void) on_device_unmount: (NSNotification*) notification; --(void) list_dev; +-(NSArray*) list_dev; @end diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.mm b/src/slic3r/GUI/RemovableDriveManagerMM.mm index 7e8b56c59b0..25fa6da0916 100644 --- a/src/slic3r/GUI/RemovableDriveManagerMM.mm +++ b/src/slic3r/GUI/RemovableDriveManagerMM.mm @@ -10,8 +10,7 @@ { self = [super init]; if(self) - { - [self add_unmount_observer]; + { } return self; } @@ -25,48 +24,49 @@ NSLog(@"add unmount observer"); [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(on_device_unmount:) name:NSWorkspaceDidUnmountNotification object:nil]; } --(void) list_dev +-(NSArray*) list_dev { - NSLog(@"---"); NSArray* devices = [[NSWorkspace sharedWorkspace] mountedRemovableMedia]; for (NSString* volumePath in devices) { - NSLog(@"@", volumePath); - } - NSLog(@"--"); - //removable here means CD not USB :/ - NSArray* listOfMedia = [[NSWorkspace sharedWorkspace] mountedLocalVolumePaths]; - NSLog(@"%@", listOfMedia); + NSLog(@"%@", volumePath); + } + return devices; - for (NSString* volumePath in listOfMedia) - { - BOOL isRemovable = NO; - BOOL isWritable = NO; - BOOL isUnmountable = NO; - NSString* description = [NSString string]; - NSString* type = [NSString string]; - - BOOL result = [[NSWorkspace sharedWorkspace] getFileSystemInfoForPath:volumePath - isRemovable:&isRemovable - isWritable:&isWritable - isUnmountable:&isUnmountable - description:&description - type:&type]; - NSLog(@"Result:%i Volume: %@, Removable:%i, W:%i, Unmountable:%i, Desc:%@, type:%@", result, volumePath, isRemovable, isWritable, isUnmountable, description, type); - } } namespace Slic3r { namespace GUI { -void RemovableDriveManager::register_window() -{ - m_rdmmm = nullptr; - m_rdmmm = [[RemovableDriveManagerMM alloc] init]; +struct RemovableDriveManagerMMImpl{ + RemovableDriveManagerMM * wrap; } -void RemovableDriveManager::list_devices() +RemovableDriveManagerMM():impl(new RemovableDriveManagerMMImpl){ + impl->wrap = [[RemovableDriveManagerMM alloc] init]; +} +RemovableDriveManagerMM::~RemovableDriveManagerMM() { - if(m_rdmmm == nullptr) - return; - [m_rdmmm list_dev]; + if(impl) + { + [impl->wrap release]; + } +} +void RDMMMWrapper::register_window() +{ + if(impl->wrap) + { + [impl->wrap add_unmount_observer]; + } +} +void RDMMMWrapper::list_devices() +{ + if(impl->wrap) + { + NSArray* devices = [impl->wrap list_dev]; + for (NSString* volumePath in devices) + { + NSLog(@"%@", volumePath); + Slic3r::GUI::RemovableDriveManager::get_instance().inspect_file(std::string([volumePath UTF8String]), "/Volumes"); + } + } } }}//namespace Slicer::GUI From 782ec0b265783f1ab2cf5aeaad00f4bff3ca69ed Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 10 Dec 2019 14:41:49 +0100 Subject: [PATCH 032/123] fix --- src/slic3r/GUI/RemovableDriveManager.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 763113ea2cf..c5dca1bd554 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -231,9 +231,10 @@ void RemovableDriveManager::search_for_drives() //search /media/* folder search_path("/media/*", "/media"); +/* //search /Volumes/* folder (OSX) search_path("/Volumes/*", "/Volumes"); - +*/ std::string path(std::getenv("USER")); std::string pp(path); //std::cout << "user: "<< path << "\n"; @@ -286,7 +287,7 @@ void RemovableDriveManager::search_path(const std::string &path,const std::strin { for(size_t i = 0; i < globbuf.gl_pathc; i++) { - + inspect_file(globbuf.gl_pathv[i], parent_path); } }else { @@ -299,11 +300,11 @@ void RemovableDriveManager::search_path(const std::string &path,const std::strin void RemovableDriveManager::inspect_file(const std::string &path, const std::string &parent_path) { //if not same file system - could be removable drive - if(!compare_filesystem_id(globbuf.gl_pathv[i], parent_path)) + if(!compare_filesystem_id(path, parent_path)) { //user id struct stat buf; - stat(globbuf.gl_pathv[i],&buf); + stat(path.c_str(), &buf); uid_t uid = buf.st_uid; std::string username(std::getenv("USER")); struct passwd *pw = getpwuid(uid); @@ -311,8 +312,8 @@ void RemovableDriveManager::inspect_file(const std::string &path, const std::str { if(pw->pw_name == username) { - std::string name = basename(globbuf.gl_pathv[i]); - m_current_drives.push_back(DriveData(name,globbuf.gl_pathv[i])); + std::string name = basename(const_cast(path.c_str())); + m_current_drives.push_back(DriveData(name,path)); } } } From 6317b449b1ae41adf3c6778fd2c032c88f254b7d Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 10 Dec 2019 17:31:27 +0100 Subject: [PATCH 033/123] Implemented "Disconnect" button --- src/slic3r/GUI/Plater.cpp | 41 ++++++++++++++++++++++++++++++++------- src/slic3r/GUI/Plater.hpp | 1 + 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index d1ce50f41f4..b50f6f150d9 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -700,6 +700,7 @@ struct Sidebar::priv wxButton *btn_export_gcode; wxButton *btn_reslice; wxButton *btn_send_gcode; + ScalableButton *btn_disconnect; priv(Plater *plater) : plater(plater) {} ~priv(); @@ -848,22 +849,39 @@ Sidebar::Sidebar(Plater *parent) // Buttons underneath the scrolled area - auto init_btn = [this](wxButton **btn, wxString label) { + auto init_btn = [this](wxButton **btn, wxString label, const std::string icon_name = "", wxString tooltip = wxEmptyString) { *btn = new wxButton(this, wxID_ANY, label, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); (*btn)->SetFont(wxGetApp().bold_font()); + (*btn)->SetToolTip(tooltip); + + if (!icon_name.empty()) + (*btn)->SetBitmap(create_scaled_bitmap(this, icon_name)); }; - init_btn(&p->btn_send_gcode, _(L("Send to printer"))); + init_btn(&p->btn_send_gcode, /*_(L("Send to printer"))*/"", "export_gcode", _(L("Send to printer"))); p->btn_send_gcode->Hide(); init_btn(&p->btn_export_gcode, _(L("Export G-code")) + dots); init_btn(&p->btn_reslice, _(L("Slice now"))); + + p->btn_disconnect = new ScalableButton(this, wxID_ANY, "revert_all_", "", + wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT); + p->btn_disconnect->Hide(); + p->btn_disconnect->SetToolTip(_(L("Remove device"))); + enable_buttons(false); auto *btns_sizer = new wxBoxSizer(wxVERTICAL); + + auto* complect_btns_sizer = new wxBoxSizer(wxHORIZONTAL); + complect_btns_sizer->Add(p->btn_export_gcode, 1, wxEXPAND); + complect_btns_sizer->Add(p->btn_send_gcode, 0, wxEXPAND); + complect_btns_sizer->Add(p->btn_disconnect); + btns_sizer->Add(p->btn_reslice, 0, wxEXPAND | wxTOP, margin_5); - btns_sizer->Add(p->btn_send_gcode, 0, wxEXPAND | wxTOP, margin_5); - btns_sizer->Add(p->btn_export_gcode, 0, wxEXPAND | wxTOP, margin_5); + btns_sizer->Add(complect_btns_sizer, 0, wxEXPAND | wxTOP, margin_5); +// btns_sizer->Add(p->btn_send_gcode, 0, wxEXPAND | wxTOP, margin_5); +// btns_sizer->Add(p->btn_export_gcode, 0, wxEXPAND | wxTOP, margin_5); auto *sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(p->scrolled, 1, wxEXPAND); @@ -882,6 +900,9 @@ Sidebar::Sidebar(Plater *parent) p->plater->select_view_3D("Preview"); }); p->btn_send_gcode->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->send_gcode(); }); + p->btn_disconnect->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { + // #dk_FIXME + }); } Sidebar::~Sidebar() {} @@ -1255,11 +1276,13 @@ void Sidebar::enable_buttons(bool enable) p->btn_reslice->Enable(enable); p->btn_export_gcode->Enable(enable); p->btn_send_gcode->Enable(enable); + p->btn_disconnect->Enable(enable); } bool Sidebar::show_reslice(bool show) const { return p->btn_reslice->Show(show); } bool Sidebar::show_export(bool show) const { return p->btn_export_gcode->Show(show); } bool Sidebar::show_send(bool show) const { return p->btn_send_gcode->Show(show); } +bool Sidebar::show_disconnect(bool show)const { return p->btn_disconnect->Show(show); } bool Sidebar::is_multifilament() { @@ -4019,20 +4042,24 @@ void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const wxWindowUpdateLocker noUpdater(sidebar); const auto prin_host_opt = config->option("print_host"); const bool send_gcode_shown = prin_host_opt != nullptr && !prin_host_opt->value.empty(); + + const bool disconnect_shown = true; // #dk_FIXME // when a background processing is ON, export_btn and/or send_btn are showing if (wxGetApp().app_config->get("background_processing") == "1") { if (sidebar->show_reslice(false) | sidebar->show_export(true) | - sidebar->show_send(send_gcode_shown)) + sidebar->show_send(send_gcode_shown) | + sidebar->show_disconnect(disconnect_shown)) sidebar->Layout(); } else { if (sidebar->show_reslice(is_ready_to_slice) | sidebar->show_export(!is_ready_to_slice) | - sidebar->show_send(send_gcode_shown && !is_ready_to_slice)) + sidebar->show_send(send_gcode_shown && !is_ready_to_slice) | + sidebar->show_disconnect(disconnect_shown && !is_ready_to_slice)) sidebar->Layout(); } } @@ -4273,7 +4300,7 @@ void Sidebar::set_btn_label(const ActionButtonType btn_type, const wxString& lab { case ActionButtonType::abReslice: p->btn_reslice->SetLabelText(label); break; case ActionButtonType::abExport: p->btn_export_gcode->SetLabelText(label); break; - case ActionButtonType::abSendGCode: p->btn_send_gcode->SetLabelText(label); break; + case ActionButtonType::abSendGCode: /*p->btn_send_gcode->SetLabelText(label);*/ break; } } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 5c36dbf5e01..af4b989c423 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -119,6 +119,7 @@ public: bool show_reslice(bool show) const; bool show_export(bool show) const; bool show_send(bool show) const; + bool show_disconnect(bool show)const; bool is_multifilament(); void update_mode(); From 25c1fba0e0810bb6a4357d6c9a8c73b664a176e7 Mon Sep 17 00:00:00 2001 From: Slic3rPE Date: Wed, 11 Dec 2019 10:16:32 +0100 Subject: [PATCH 034/123] macos better wrapper --- src/slic3r/GUI/RemovableDriveManager.hpp | 29 +++++++++++++---------- src/slic3r/GUI/RemovableDriveManagerMM.mm | 21 +++++++--------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 202680328eb..cbf6f53aac5 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -6,6 +6,10 @@ namespace Slic3r { namespace GUI { +class RDMMMWrapper; +#if __APPLE__ + + struct DriveData { std::string name; @@ -57,25 +61,24 @@ private: //INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); #else #if __APPLE__ - RemovableDriveManagerMM * m_rdmmm; + RDMMMWrapper * m_rdmmm; #endif void search_path(const std::string &path, const std::string &parent_path); void inspect_file(const std::string &path, const std::string &parent_path); bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); #endif }; -#if __APPLE__ -class RemovableDriveManagerMM -{ -public: - RemovableDriveManagerMM(); - ~RemovableDriveManagerMM(); - register_window(); - list_devices(); -private: - RemovableDriveManagerMMImpl *m_imp; - friend void RemovableDriveManager::inspect_file(const std::string &path, const std::string &parent_path); -}; + class RDMMMWrapper + { + public: + RDMMMWrapper(); + ~RDMMMWrapper(); + void register_window(); + void list_devices(); + private: + void *m_imp; + friend void RemovableDriveManager::inspect_file(const std::string &path, const std::string &parent_path); + }; #endif }} #endif diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.mm b/src/slic3r/GUI/RemovableDriveManagerMM.mm index 25fa6da0916..269a2255b0c 100644 --- a/src/slic3r/GUI/RemovableDriveManagerMM.mm +++ b/src/slic3r/GUI/RemovableDriveManagerMM.mm @@ -36,31 +36,28 @@ } namespace Slic3r { namespace GUI { -struct RemovableDriveManagerMMImpl{ - RemovableDriveManagerMM * wrap; +RDMMMWrapper::RDMMMWrapper():m_imp(nullptr){ + m_imp = [[RemovableDriveManagerMM alloc] init]; } -RemovableDriveManagerMM():impl(new RemovableDriveManagerMMImpl){ - impl->wrap = [[RemovableDriveManagerMM alloc] init]; -} -RemovableDriveManagerMM::~RemovableDriveManagerMM() +RDMMMWrapper::~RDMMMWrapper() { - if(impl) + if(m_imp) { - [impl->wrap release]; + [m_imp release]; } } void RDMMMWrapper::register_window() { - if(impl->wrap) + if(m_imp) { - [impl->wrap add_unmount_observer]; + [m_imp add_unmount_observer]; } } void RDMMMWrapper::list_devices() { - if(impl->wrap) + if(m_imp) { - NSArray* devices = [impl->wrap list_dev]; + NSArray* devices = [m_imp list_dev]; for (NSString* volumePath in devices) { NSLog(@"%@", volumePath); From a7ade77d18cbacd3ee894ed6cf85b13f44b66e0a Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 11 Dec 2019 11:00:23 +0100 Subject: [PATCH 035/123] Added missed icon --- resources/icons/revert_all_.svg | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 resources/icons/revert_all_.svg diff --git a/resources/icons/revert_all_.svg b/resources/icons/revert_all_.svg new file mode 100644 index 00000000000..fe8de635db4 --- /dev/null +++ b/resources/icons/revert_all_.svg @@ -0,0 +1,9 @@ + + + + + Svg Vector Icons : http://www.onlinewebfonts.com/icon + + + + \ No newline at end of file From 3583962f9c86c6d9bd5e48b86fea03be4c17947c Mon Sep 17 00:00:00 2001 From: Slic3rPE Date: Wed, 11 Dec 2019 11:00:47 +0100 Subject: [PATCH 036/123] macos better wrapper --- src/slic3r/GUI/RemovableDriveManager.cpp | 12 ++++++- src/slic3r/GUI/RemovableDriveManager.hpp | 40 ++++++++++++----------- src/slic3r/GUI/RemovableDriveManagerMM.mm | 4 --- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index c5dca1bd554..164b6e38aa8 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -391,13 +391,23 @@ std::string RemovableDriveManager::get_drive_from_path(const std::string& path) return ""; } #endif + +RemovableDriveManager::RemovableDriveManager(): + m_drives_count(0), + m_last_update(0), + m_last_save_path(""), +#if __APPLE__ + m_rdmmm(new RDMMMWrapper()) +#endif +{} + void RemovableDriveManager::init() { add_callback([](void) { RemovableDriveManager::get_instance().print(); }); #if _WIN32 register_window(); #elif __APPLE__ - register_window(); + m_rdmmm->register_window(); #endif update(); } diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index cbf6f53aac5..a5027a5adf8 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -6,9 +6,9 @@ namespace Slic3r { namespace GUI { -class RDMMMWrapper; #if __APPLE__ - +class RDMMMWrapper; +#endif struct DriveData { @@ -18,6 +18,9 @@ struct DriveData }; class RemovableDriveManager { +#if __APPLE__ +friend class RDMMMWrapper; +#endif public: static RemovableDriveManager& get_instance() { @@ -42,12 +45,9 @@ public: bool is_last_drive_removed_with_update(const long time = 0); // param as update() void reset_last_save_path(); void print(); + private: -#if __APPLE__ - RemovableDriveManager():m_drives_count(0),m_last_update(0),m_last_save_path(""),m_rdmmm(new RemovableDriveManagerMM()){} -#else - RemovableDriveManager() : m_drives_count(0), m_last_update(0), m_last_save_path(""){} -#endif + RemovableDriveManager(); void search_for_drives(); void check_and_notify(); std::string get_drive_from_path(const std::string& path);//returns drive path (same as path in DriveData) if exists otherwise empty string "" @@ -64,21 +64,23 @@ private: RDMMMWrapper * m_rdmmm; #endif void search_path(const std::string &path, const std::string &parent_path); - void inspect_file(const std::string &path, const std::string &parent_path); bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); + void inspect_file(const std::string &path, const std::string &parent_path); #endif }; - class RDMMMWrapper - { - public: - RDMMMWrapper(); - ~RDMMMWrapper(); - void register_window(); - void list_devices(); - private: - void *m_imp; - friend void RemovableDriveManager::inspect_file(const std::string &path, const std::string &parent_path); - }; + +#if __APPLE__ +class RDMMMWrapper +{ +public: + RDMMMWrapper(); + ~RDMMMWrapper(); + void register_window(); + void list_devices(); +protected: + void *m_imp; + //friend void RemovableDriveManager::inspect_file(const std::string &path, const std::string &parent_path); +}; #endif }} #endif diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.mm b/src/slic3r/GUI/RemovableDriveManagerMM.mm index 269a2255b0c..d32b7b278e5 100644 --- a/src/slic3r/GUI/RemovableDriveManagerMM.mm +++ b/src/slic3r/GUI/RemovableDriveManagerMM.mm @@ -27,10 +27,6 @@ -(NSArray*) list_dev { NSArray* devices = [[NSWorkspace sharedWorkspace] mountedRemovableMedia]; - for (NSString* volumePath in devices) - { - NSLog(@"%@", volumePath); - } return devices; } From f4c8e90d773fad570682505cf9d6db6ef0e2037f Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 11 Dec 2019 12:28:51 +0100 Subject: [PATCH 037/123] eject button functionality --- src/slic3r/GUI/Plater.cpp | 19 ++++++++++++++++++- src/slic3r/GUI/Plater.hpp | 2 ++ src/slic3r/GUI/RemovableDriveManager.cpp | 22 +++++++++------------- src/slic3r/GUI/RemovableDriveManager.hpp | 8 +++++--- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index b50f6f150d9..e94e0a4e639 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -902,6 +902,7 @@ Sidebar::Sidebar(Plater *parent) p->btn_send_gcode->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->send_gcode(); }); p->btn_disconnect->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { // #dk_FIXME + p->plater->eject_drive(); }); } @@ -4043,7 +4044,7 @@ void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const const auto prin_host_opt = config->option("print_host"); const bool send_gcode_shown = prin_host_opt != nullptr && !prin_host_opt->value.empty(); - const bool disconnect_shown = true; // #dk_FIXME + const bool disconnect_shown = !(RemovableDriveManager::get_instance().is_last_drive_removed()); // #dk_FIXME // when a background processing is ON, export_btn and/or send_btn are showing if (wxGetApp().app_config->get("background_processing") == "1") @@ -4886,6 +4887,22 @@ void Plater::send_gcode() } } +void Plater::eject_drive() +{ + if (GUI::RemovableDriveManager::get_instance().update()) + { + RemovableDriveManager::get_instance().erase_callbacks(); + RemovableDriveManager::get_instance().add_callback(std::bind(&Plater::drive_ejected_callback, this)); + RemovableDriveManager::get_instance().eject_drive(RemovableDriveManager::get_instance().get_last_drive_path()); + } +} +void Plater::drive_ejected_callback() +{ + p->show_action_buttons(false); +} + + + void Plater::take_snapshot(const std::string &snapshot_name) { p->take_snapshot(snapshot_name); } void Plater::take_snapshot(const wxString &snapshot_name) { p->take_snapshot(snapshot_name); } void Plater::suppress_snapshots() { p->suppress_snapshots(); } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index af4b989c423..a247f82922d 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -202,6 +202,8 @@ public: void suppress_background_process(const bool stop_background_process) ; void fix_through_netfabb(const int obj_idx, const int vol_idx = -1); void send_gcode(); + void eject_drive(); + void drive_ejected_callback(); void take_snapshot(const std::string &snapshot_name); void take_snapshot(const wxString &snapshot_name); diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 164b6e38aa8..1a964f889dc 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -395,9 +395,9 @@ std::string RemovableDriveManager::get_drive_from_path(const std::string& path) RemovableDriveManager::RemovableDriveManager(): m_drives_count(0), m_last_update(0), - m_last_save_path(""), + m_last_save_path("") #if __APPLE__ - m_rdmmm(new RDMMMWrapper()) + , m_rdmmm(new RDMMMWrapper()) #endif {} @@ -411,7 +411,7 @@ void RemovableDriveManager::init() #endif update(); } -bool RemovableDriveManager::update(const long time) +bool RemovableDriveManager::update(const long time, bool check) { if(time != 0) //time = 0 is forced update { @@ -425,7 +425,7 @@ bool RemovableDriveManager::update(const long time) } } search_for_drives(); - check_and_notify(); + if(check)check_and_notify(); return !m_current_drives.empty(); } @@ -444,13 +444,7 @@ bool RemovableDriveManager::is_drive_mounted(const std::string &path) std::string RemovableDriveManager::get_last_drive_path() { - if (!m_current_drives.empty()) - { - if (m_last_save_path != "") - return m_last_save_path; - return m_current_drives.back().path; - } - return ""; + return m_last_save_path; } std::vector RemovableDriveManager::get_all_drives() { @@ -495,11 +489,13 @@ bool RemovableDriveManager::is_last_drive_removed() { return true; } - return !is_drive_mounted(m_last_save_path); + bool r = !is_drive_mounted(m_last_save_path); + if (r) reset_last_save_path(); + return r; } bool RemovableDriveManager::is_last_drive_removed_with_update(const long time) { - update(time); + update(time, false); return is_last_drive_removed(); } void RemovableDriveManager::reset_last_save_path() diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index a5027a5adf8..f412940010f 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -32,7 +32,7 @@ public: //update() searches for removable devices, returns false if empty. void init(); - bool update(const long time = 0); //time = 0 is forced update, time expects wxGetLocalTime() + bool update(const long time = 0, bool check = true); //time = 0 is forced update, time expects wxGetLocalTime() bool is_drive_mounted(const std::string &path); void eject_drive(const std::string &path); std::string get_last_drive_path(); @@ -41,9 +41,8 @@ public: void add_callback(std::function callback); // callback will notify only if device with last save path was removed void erase_callbacks(); // erases all callbacks added by add_callback() void set_last_save_path(const std::string &path); - bool is_last_drive_removed(); //if we dont need info about this drive, call reset_last_save_path(); + bool is_last_drive_removed(); bool is_last_drive_removed_with_update(const long time = 0); // param as update() - void reset_last_save_path(); void print(); private: @@ -51,11 +50,14 @@ private: void search_for_drives(); void check_and_notify(); std::string get_drive_from_path(const std::string& path);//returns drive path (same as path in DriveData) if exists otherwise empty string "" + void reset_last_save_path(); + std::vector m_current_drives; std::vector> m_callbacks; size_t m_drives_count; long m_last_update; std::string m_last_save_path; + #if _WIN32 void register_window(); //INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); From d395e5bccfdf9c56046d463f9da96539f553d97d Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 11 Dec 2019 14:53:28 +0100 Subject: [PATCH 038/123] eject button functionality --- src/slic3r/GUI/GUI_App.cpp | 2 +- src/slic3r/GUI/Plater.cpp | 6 +++--- src/slic3r/GUI/RemovableDriveManager.cpp | 24 +++++++++++++++++------ src/slic3r/GUI/RemovableDriveManager.hpp | 5 +++-- src/slic3r/GUI/RemovableDriveManagerMM.mm | 2 +- 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 1b2fe919a22..fc25b4f2956 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -273,7 +273,7 @@ bool GUI_App::on_init_inner() this->obj_manipul()->update_if_dirty(); - //RemovableDriveManager::get_instance().update(wxGetLocalTime()); + RemovableDriveManager::get_instance().update(wxGetLocalTime(), true); // Preset updating & Configwizard are done after the above initializations, diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index e94e0a4e639..905d56e900f 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4588,7 +4588,7 @@ void Plater::export_gcode() { if (!RemovableDriveManager::get_instance().is_path_on_removable_drive(start_dir)) { - start_dir = RemovableDriveManager::get_instance().get_last_drive_path(); + start_dir = RemovableDriveManager::get_instance().get_drive_path(); } } wxFileDialog dlg(this, (printer_technology() == ptFFF) ? _(L("Save G-code file as:")) : _(L("Save SL1 file as:")), @@ -4889,11 +4889,11 @@ void Plater::send_gcode() void Plater::eject_drive() { - if (GUI::RemovableDriveManager::get_instance().update()) + if (GUI::RemovableDriveManager::get_instance().update(0, true)) { RemovableDriveManager::get_instance().erase_callbacks(); RemovableDriveManager::get_instance().add_callback(std::bind(&Plater::drive_ejected_callback, this)); - RemovableDriveManager::get_instance().eject_drive(RemovableDriveManager::get_instance().get_last_drive_path()); + RemovableDriveManager::get_instance().eject_drive(RemovableDriveManager::get_instance().get_last_save_path()); } } void Plater::drive_ejected_callback() diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 1a964f889dc..49bf59e11fe 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -198,15 +198,16 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP DEVICE_NOTIFY_WINDOW_HANDLE // type of recipient handle ); break; + /* case WM_DEVICECHANGE: { if(wParam == DBT_DEVICEREMOVECOMPLETE) { - std::cout << "WM_DEVICECHANGE\n"; - RemovableDriveManager::get_instance().update(); +- RemovableDriveManager::get_instance().update(0, true); } } break; + */ default: // Send all other messages on to the default windows handler. lRet = DefWindowProc(hWnd, message, wParam, lParam); @@ -403,7 +404,7 @@ RemovableDriveManager::RemovableDriveManager(): void RemovableDriveManager::init() { - add_callback([](void) { RemovableDriveManager::get_instance().print(); }); + //add_callback([](void) { RemovableDriveManager::get_instance().print(); }); #if _WIN32 register_window(); #elif __APPLE__ @@ -441,8 +442,18 @@ bool RemovableDriveManager::is_drive_mounted(const std::string &path) } return false; } - -std::string RemovableDriveManager::get_last_drive_path() +std::string RemovableDriveManager::get_drive_path() +{ + if (m_current_drives.size() == 0) + { + reset_last_save_path(); + return ""; + } + if (m_last_save_path != "") + return m_last_save_path; + return m_current_drives.back().path; +} +std::string RemovableDriveManager::get_last_save_path() { return m_last_save_path; } @@ -456,7 +467,7 @@ void RemovableDriveManager::check_and_notify() if(m_drives_count != m_current_drives.size()) { //std::cout<<" vs "<< m_current_drives.size(); - if(m_drives_count > m_current_drives.size() && m_last_save_path != "" && !is_drive_mounted(m_last_save_path)) + if(m_callbacks.size() != 0 && m_drives_count > m_current_drives.size() && m_last_save_path != "" && !is_drive_mounted(m_last_save_path)) { for (auto it = m_callbacks.begin(); it != m_callbacks.end(); ++it) { @@ -485,6 +496,7 @@ void RemovableDriveManager::set_last_save_path(const std::string& path) } bool RemovableDriveManager::is_last_drive_removed() { + m_drives_count = m_current_drives.size(); if(m_last_save_path == "") { return true; diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index f412940010f..49df4148270 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -32,10 +32,11 @@ public: //update() searches for removable devices, returns false if empty. void init(); - bool update(const long time = 0, bool check = true); //time = 0 is forced update, time expects wxGetLocalTime() + bool update(const long time = 0, bool check = false); //time = 0 is forced update, time expects wxGetLocalTime() bool is_drive_mounted(const std::string &path); void eject_drive(const std::string &path); - std::string get_last_drive_path(); + std::string get_last_save_path(); + std::string get_drive_path(); std::vector get_all_drives(); bool is_path_on_removable_drive(const std::string &path); void add_callback(std::function callback); // callback will notify only if device with last save path was removed diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.mm b/src/slic3r/GUI/RemovableDriveManagerMM.mm index d32b7b278e5..7a1108541a5 100644 --- a/src/slic3r/GUI/RemovableDriveManagerMM.mm +++ b/src/slic3r/GUI/RemovableDriveManagerMM.mm @@ -17,7 +17,7 @@ -(void) on_device_unmount: (NSNotification*) notification { NSLog(@"on device change"); - Slic3r::GUI::RemovableDriveManager::get_instance().update(); + Slic3r::GUI::RemovableDriveManager::get_instance().update(0,true); } -(void) add_unmount_observer { From ea788de4b5d9a775c33ba265b7ab6073d00990f1 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 11 Dec 2019 15:02:20 +0100 Subject: [PATCH 039/123] eject button functionality --- src/slic3r/GUI/Plater.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 905d56e900f..0300670e484 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4603,7 +4603,9 @@ void Plater::export_gcode() fs::path path = into_path(dlg.GetPath()); wxGetApp().app_config->update_last_output_dir(path.parent_path().string()); output_path = std::move(path); - RemovableDriveManager::get_instance().set_last_save_path(output_path.string()); + RemovableDriveManager::get_instance().update(0, true); + RemovableDriveManager::get_instance().set_last_save_path(output_path.string()); + } if (! output_path.empty()) p->export_gcode(std::move(output_path), PrintHostJob()); From 66cfbc7a9dbac4404b2900170d596d7d9fe4de54 Mon Sep 17 00:00:00 2001 From: Slic3rPE Date: Wed, 11 Dec 2019 16:59:26 +0100 Subject: [PATCH 040/123] macos eject --- src/slic3r/GUI/GUI_App.cpp | 2 +- src/slic3r/GUI/RemovableDriveManager.cpp | 5 +++++ src/slic3r/GUI/RemovableDriveManager.hpp | 1 + src/slic3r/GUI/RemovableDriveManagerMM.mm | 4 ++++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index fc25b4f2956..8e450f4972f 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -273,7 +273,7 @@ bool GUI_App::on_init_inner() this->obj_manipul()->update_if_dirty(); - RemovableDriveManager::get_instance().update(wxGetLocalTime(), true); + //RemovableDriveManager::get_instance().update(wxGetLocalTime(), true); // Preset updating & Configwizard are done after the above initializations, diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 49bf59e11fe..284c224fbd2 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -425,6 +425,10 @@ bool RemovableDriveManager::update(const long time, bool check) return false; // return value shouldnt matter if update didnt run } } + if(check) + { + m_rdmmm->log("update"); + } search_for_drives(); if(check)check_and_notify(); return !m_current_drives.empty(); @@ -466,6 +470,7 @@ void RemovableDriveManager::check_and_notify() //std::cout<<"drives count: "<log("drives count not same"); //std::cout<<" vs "<< m_current_drives.size(); if(m_callbacks.size() != 0 && m_drives_count > m_current_drives.size() && m_last_save_path != "" && !is_drive_mounted(m_last_save_path)) { diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 49df4148270..9eea355f79a 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -80,6 +80,7 @@ public: ~RDMMMWrapper(); void register_window(); void list_devices(); + void log(const std::string &msg); protected: void *m_imp; //friend void RemovableDriveManager::inspect_file(const std::string &path, const std::string &parent_path); diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.mm b/src/slic3r/GUI/RemovableDriveManagerMM.mm index 7a1108541a5..45bd21bcfaa 100644 --- a/src/slic3r/GUI/RemovableDriveManagerMM.mm +++ b/src/slic3r/GUI/RemovableDriveManagerMM.mm @@ -61,6 +61,10 @@ void RDMMMWrapper::list_devices() } } } +void RDMMMWrapper::log(const std::string &msg) +{ + NSLog(@"%s", msg.c_str()); +} }}//namespace Slicer::GUI /* From 19daba4ff90e706037f89eafb8f7bea89eb8b702 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 11 Dec 2019 17:02:12 +0100 Subject: [PATCH 041/123] eject button functionality --- src/slic3r/GUI/GUI_App.cpp | 2 +- src/slic3r/GUI/RemovableDriveManager.cpp | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index fc25b4f2956..8e450f4972f 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -273,7 +273,7 @@ bool GUI_App::on_init_inner() this->obj_manipul()->update_if_dirty(); - RemovableDriveManager::get_instance().update(wxGetLocalTime(), true); + //RemovableDriveManager::get_instance().update(wxGetLocalTime(), true); // Preset updating & Configwizard are done after the above initializations, diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 49bf59e11fe..dc8469d9a24 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -96,14 +96,16 @@ void RemovableDriveManager::eject_drive(const std::string &path) return; } DWORD deviceControlRetVal(0); + DeviceIoControl(handle, FSCTL_LOCK_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); + DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); - CloseHandle(handle); if (error == 0) { + CloseHandle(handle); std::cerr << "Ejecting " << mpath << " failed " << deviceControlRetVal << " " << GetLastError() << " \n"; return; } - + CloseHandle(handle); m_current_drives.erase(it); break; @@ -198,7 +200,7 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP DEVICE_NOTIFY_WINDOW_HANDLE // type of recipient handle ); break; - /* + case WM_DEVICECHANGE: { if(wParam == DBT_DEVICEREMOVECOMPLETE) @@ -207,7 +209,7 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP } } break; - */ + default: // Send all other messages on to the default windows handler. lRet = DefWindowProc(hWnd, message, wParam, lParam); From 1450c9240497ad168c434602d3e772c8465431ed Mon Sep 17 00:00:00 2001 From: Slic3rPE Date: Wed, 11 Dec 2019 17:39:34 +0100 Subject: [PATCH 042/123] macos eject --- src/slic3r/GUI/RemovableDriveManager.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index afe5ee73939..ab2dd10eb20 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -221,15 +221,17 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP #else void RemovableDriveManager::search_for_drives() { - + + m_current_drives.clear(); + m_current_drives.reserve(26); + #if __APPLE__ if(m_rdmmm) { m_rdmmm->list_devices(); } #else - m_current_drives.clear(); - m_current_drives.reserve(26); + //search /media/* folder search_path("/media/*", "/media"); From e819cb154690cae888697e7c88a3416f03bd3946 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 11 Dec 2019 17:42:56 +0100 Subject: [PATCH 043/123] eject button functionality --- src/slic3r/GUI/Plater.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 0300670e484..a0e453abc3d 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4891,12 +4891,11 @@ void Plater::send_gcode() void Plater::eject_drive() { - if (GUI::RemovableDriveManager::get_instance().update(0, true)) - { - RemovableDriveManager::get_instance().erase_callbacks(); - RemovableDriveManager::get_instance().add_callback(std::bind(&Plater::drive_ejected_callback, this)); - RemovableDriveManager::get_instance().eject_drive(RemovableDriveManager::get_instance().get_last_save_path()); - } + RemovableDriveManager::get_instance().update(0, true); + RemovableDriveManager::get_instance().erase_callbacks(); + RemovableDriveManager::get_instance().add_callback(std::bind(&Plater::drive_ejected_callback, this)); + RemovableDriveManager::get_instance().eject_drive(RemovableDriveManager::get_instance().get_last_save_path()); + } void Plater::drive_ejected_callback() { From 576b36066a3911dc56b0d51d9158e81a829279f2 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 11 Dec 2019 18:30:03 +0100 Subject: [PATCH 044/123] linux eject --- src/slic3r/GUI/GUI_App.cpp | 6 +++--- src/slic3r/GUI/RemovableDriveManager.cpp | 9 ++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 8e450f4972f..258e3387191 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -272,9 +272,9 @@ bool GUI_App::on_init_inner() this->obj_manipul()->update_if_dirty(); - - //RemovableDriveManager::get_instance().update(wxGetLocalTime(), true); - +#if __linux__ + RemovableDriveManager::get_instance().update(wxGetLocalTime(), true); +#endif // Preset updating & Configwizard are done after the above initializations, // and after MainFrame is created & shown. diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index ab2dd10eb20..d5f2244095f 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -429,10 +429,6 @@ bool RemovableDriveManager::update(const long time, bool check) return false; // return value shouldnt matter if update didnt run } } - if(check) - { - m_rdmmm->log("update"); - } search_for_drives(); if(check)check_and_notify(); return !m_current_drives.empty(); @@ -474,7 +470,7 @@ void RemovableDriveManager::check_and_notify() //std::cout<<"drives count: "<log("drives count not same"); + //m_rdmmm->log("drives count not same"); //std::cout<<" vs "<< m_current_drives.size(); if(m_callbacks.size() != 0 && m_drives_count > m_current_drives.size() && m_last_save_path != "" && !is_drive_mounted(m_last_save_path)) { @@ -505,13 +501,16 @@ void RemovableDriveManager::set_last_save_path(const std::string& path) } bool RemovableDriveManager::is_last_drive_removed() { + std::cout<<"is last: "< Date: Thu, 12 Dec 2019 10:48:33 +0100 Subject: [PATCH 045/123] eject button after export --- src/slic3r/GUI/GUI_App.cpp | 2 +- src/slic3r/GUI/Plater.cpp | 9 +++++---- src/slic3r/GUI/RemovableDriveManager.cpp | 8 ++++---- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 258e3387191..bdaf8f8a797 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -272,7 +272,7 @@ bool GUI_App::on_init_inner() this->obj_manipul()->update_if_dirty(); -#if __linux__ +#if !__APPLE__ RemovableDriveManager::get_instance().update(wxGetLocalTime(), true); #endif diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index a0e453abc3d..74a26c40020 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4052,7 +4052,7 @@ void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const if (sidebar->show_reslice(false) | sidebar->show_export(true) | sidebar->show_send(send_gcode_shown) | - sidebar->show_disconnect(disconnect_shown)) + sidebar->show_disconnect(false/*disconnect_shown*/)) sidebar->Layout(); } else @@ -4603,12 +4603,13 @@ void Plater::export_gcode() fs::path path = into_path(dlg.GetPath()); wxGetApp().app_config->update_last_output_dir(path.parent_path().string()); output_path = std::move(path); - RemovableDriveManager::get_instance().update(0, true); - RemovableDriveManager::get_instance().set_last_save_path(output_path.string()); - } if (! output_path.empty()) + { + RemovableDriveManager::get_instance().update(0, true); + RemovableDriveManager::get_instance().set_last_save_path(output_path.string()); p->export_gcode(std::move(output_path), PrintHostJob()); + } } diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index d5f2244095f..7ab34204bc2 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -410,7 +410,7 @@ void RemovableDriveManager::init() { //add_callback([](void) { RemovableDriveManager::get_instance().print(); }); #if _WIN32 - register_window(); + //register_window(); #elif __APPLE__ m_rdmmm->register_window(); #endif @@ -501,16 +501,16 @@ void RemovableDriveManager::set_last_save_path(const std::string& path) } bool RemovableDriveManager::is_last_drive_removed() { - std::cout<<"is last: "< Date: Thu, 12 Dec 2019 14:56:30 +0100 Subject: [PATCH 046/123] button show after write --- src/slic3r/GUI/Plater.cpp | 8 ++++-- src/slic3r/GUI/RemovableDriveManager.cpp | 35 +++--------------------- src/slic3r/GUI/RemovableDriveManager.hpp | 4 +-- 3 files changed, 10 insertions(+), 37 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 74a26c40020..3ecb174ce99 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3171,6 +3171,7 @@ void Plater::priv::update_fff_scene() this->preview->reload_print(); // In case this was MM print, wipe tower bounding box on 3D tab might need redrawing with exact depth: view3D->reload_scene(true); + show_action_buttons(false); } void Plater::priv::update_sla_scene() @@ -4052,7 +4053,7 @@ void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const if (sidebar->show_reslice(false) | sidebar->show_export(true) | sidebar->show_send(send_gcode_shown) | - sidebar->show_disconnect(false/*disconnect_shown*/)) + sidebar->show_disconnect(disconnect_shown)) sidebar->Layout(); } else @@ -4606,9 +4607,10 @@ void Plater::export_gcode() } if (! output_path.empty()) { - RemovableDriveManager::get_instance().update(0, true); - RemovableDriveManager::get_instance().set_last_save_path(output_path.string()); + std::string path = output_path.string(); p->export_gcode(std::move(output_path), PrintHostJob()); + RemovableDriveManager::get_instance().update(0, true); + RemovableDriveManager::get_instance().set_last_save_path(path); } } diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 7ab34204bc2..cd360b580f3 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -24,9 +24,6 @@ GUID WceusbshGUID = { 0x25dbce51, 0x6c8f, 0x4a72, namespace Slic3r { namespace GUI { -//std::vector RemovableDriveManager::m_current_drives; -//std::vector> RemovableDriveManager::m_callbacks; - #if _WIN32 INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); @@ -42,7 +39,6 @@ void RemovableDriveManager::search_for_drives() std::string path (1,(char)('A' + i)); path+=":"; UINT drive_type = GetDriveTypeA(path.c_str()); - //std::cout << "found drive" << (char)('A' + i) << ": type:" < 0) { path += "\\"; @@ -74,12 +69,9 @@ void RemovableDriveManager::search_for_drives() } } } - //std::cout << "found drives:" << m_current_drives.size() << "\n"; } void RemovableDriveManager::eject_drive(const std::string &path) { - - //if (!update() || !is_drive_mounted(path)) if(m_current_drives.empty()) return; for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) @@ -88,7 +80,6 @@ void RemovableDriveManager::eject_drive(const std::string &path) { std::string mpath = "\\\\.\\" + path; mpath = mpath.substr(0, mpath.size() - 1); - //std::cout << "Ejecting " << mpath << "\n"; HANDLE handle = CreateFileA(mpath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); if (handle == INVALID_HANDLE_VALUE) { @@ -138,7 +129,7 @@ std::string RemovableDriveManager::get_drive_from_path(const std::string& path) } void RemovableDriveManager::register_window() { - std::cout << "Registering for device notification\n"; + //creates new unvisible window that is recieving callbacks from system WNDCLASSEX wndClass; wndClass.cbSize = sizeof(WNDCLASSEX); wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; @@ -181,9 +172,6 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP LRESULT lRet = 1; static HDEVNOTIFY hDeviceNotify; - static HWND hEditWnd; - static ULONGLONG msgCount = 0; - switch (message) { case WM_CREATE: @@ -194,11 +182,7 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; NotificationFilter.dbcc_classguid = WceusbshGUID; - hDeviceNotify = RegisterDeviceNotification( - hWnd, // events recipient - &NotificationFilter, // type of device - DEVICE_NOTIFY_WINDOW_HANDLE // type of recipient handle - ); + hDeviceNotify = RegisterDeviceNotification(hWnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE); break; case WM_DEVICECHANGE: @@ -280,7 +264,6 @@ void RemovableDriveManager::search_for_drives() } - //std::cout << "found drives:" < RemovableDriveManager::get_all_drives() } void RemovableDriveManager::check_and_notify() { - //std::cout<<"drives count: "<log("drives count not same"); - //std::cout<<" vs "<< m_current_drives.size(); if(m_callbacks.size() != 0 && m_drives_count > m_current_drives.size() && m_last_save_path != "" && !is_drive_mounted(m_last_save_path)) { for (auto it = m_callbacks.begin(); it != m_callbacks.end(); ++it) @@ -481,7 +461,6 @@ void RemovableDriveManager::check_and_notify() } m_drives_count = m_current_drives.size(); } - //std::cout<<"\n"; } void RemovableDriveManager::add_callback(std::function callback) { @@ -522,10 +501,4 @@ void RemovableDriveManager::reset_last_save_path() { m_last_save_path = ""; } - -void RemovableDriveManager::print() -{ - //std::cout << "Removed Device: "<<(int)is_last_drive_removed()<<"\n"; - std::cout << "notified\n"; -} -}}//namespace Slicer::Gui:: +}}//namespace Slicer::Gui diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 9eea355f79a..b4fc71e2656 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -32,7 +32,7 @@ public: //update() searches for removable devices, returns false if empty. void init(); - bool update(const long time = 0, bool check = false); //time = 0 is forced update, time expects wxGetLocalTime() + bool update(const long time = 0,const bool check = false); //time = 0 is forced update, time expects wxGetLocalTime() bool is_drive_mounted(const std::string &path); void eject_drive(const std::string &path); std::string get_last_save_path(); @@ -44,8 +44,6 @@ public: void set_last_save_path(const std::string &path); bool is_last_drive_removed(); bool is_last_drive_removed_with_update(const long time = 0); // param as update() - void print(); - private: RemovableDriveManager(); void search_for_drives(); From 15497ca0c4f90d8d8617148f513985332da62ca0 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 12 Dec 2019 15:43:14 +0100 Subject: [PATCH 047/123] button show after write --- src/slic3r/GUI/Plater.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 3ecb174ce99..417afa0a966 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3171,7 +3171,7 @@ void Plater::priv::update_fff_scene() this->preview->reload_print(); // In case this was MM print, wipe tower bounding box on 3D tab might need redrawing with exact depth: view3D->reload_scene(true); - show_action_buttons(false); + } void Plater::priv::update_sla_scene() @@ -3518,6 +3518,8 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt) default: break; } + show_action_buttons(false); + if (canceled) { if (wxGetApp().get_mode() == comSimple) sidebar->set_btn_label(ActionButtonType::abReslice, "Slice now"); From 8d40b6aa253a08abbd6ba779753227b8d2f722f6 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Fri, 13 Dec 2019 11:52:08 +0100 Subject: [PATCH 048/123] comments --- src/slic3r/GUI/RemovableDriveManager.cpp | 24 ++++++++++++++++++---- src/slic3r/GUI/RemovableDriveManager.hpp | 26 ++++++++++++++++-------- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index cd360b580f3..02681b7daf2 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -30,7 +30,7 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP void RemovableDriveManager::search_for_drives() { m_current_drives.clear(); - m_current_drives.reserve(26); + //get logical drives flags by letter in alphabetical order DWORD drives_mask = GetLogicalDrives(); for (size_t i = 0; i < 26; i++) { @@ -39,6 +39,7 @@ void RemovableDriveManager::search_for_drives() std::string path (1,(char)('A' + i)); path+=":"; UINT drive_type = GetDriveTypeA(path.c_str()); + // DRIVE_REMOVABLE on W are sd cards and usb thumbnails (not usb harddrives) if (drive_type == DRIVE_REMOVABLE) { // get name of drive @@ -51,10 +52,12 @@ void RemovableDriveManager::search_for_drives() BOOL error = GetVolumeInformationW(wpath.c_str(), &volume_name[0], sizeof(volume_name), NULL, NULL, NULL, &file_system_name[0], sizeof(file_system_name)); if(error != 0) { + /* if (volume_name == L"") { volume_name = L"REMOVABLE DRIVE"; } + */ if (file_system_name != L"") { ULARGE_INTEGER free_space; @@ -78,6 +81,7 @@ void RemovableDriveManager::eject_drive(const std::string &path) { if ((*it).path == path) { + // get handle to device std::string mpath = "\\\\.\\" + path; mpath = mpath.substr(0, mpath.size() - 1); HANDLE handle = CreateFileA(mpath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); @@ -87,8 +91,12 @@ void RemovableDriveManager::eject_drive(const std::string &path) return; } DWORD deviceControlRetVal(0); + //these 3 commands should eject device safely but they dont, the device does disappear from file explorer but the "device was safely remove" notification doesnt trigger. + //sd cards does trigger WM_DEVICECHANGE messege, usb drives dont + DeviceIoControl(handle, FSCTL_LOCK_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); + // some implemenatations also calls IOCTL_STORAGE_MEDIA_REMOVAL here but it returns error to me BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); if (error == 0) { @@ -130,11 +138,12 @@ std::string RemovableDriveManager::get_drive_from_path(const std::string& path) void RemovableDriveManager::register_window() { //creates new unvisible window that is recieving callbacks from system + // structure to register WNDCLASSEX wndClass; wndClass.cbSize = sizeof(WNDCLASSEX); wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wndClass.hInstance = reinterpret_cast(GetModuleHandle(0)); - wndClass.lpfnWndProc = reinterpret_cast(WinProcCallback); + wndClass.lpfnWndProc = reinterpret_cast(WinProcCallback);//this is callback wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 0; wndClass.hIcon = LoadIcon(0, IDI_APPLICATION); @@ -169,6 +178,9 @@ void RemovableDriveManager::register_window() INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { + // here we need to catch messeges about device removal + // problem is that when ejecting usb (how is it implemented above) there is no messege dispached. Only after physical removal of the device. + //uncomment register_window() in init() to register and comment update() in GUI_App.cpp (only for windows!) to stop recieving periodical updates LRESULT lRet = 1; static HDEVNOTIFY hDeviceNotify; @@ -187,6 +199,7 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP case WM_DEVICECHANGE: { + // here is the important if(wParam == DBT_DEVICEREMOVECOMPLETE) { - RemovableDriveManager::get_instance().update(0, true); @@ -207,9 +220,9 @@ void RemovableDriveManager::search_for_drives() { m_current_drives.clear(); - m_current_drives.reserve(26); #if __APPLE__ + // if on macos obj-c class will enumerate if(m_rdmmm) { m_rdmmm->list_devices(); @@ -287,6 +300,8 @@ void RemovableDriveManager::search_path(const std::string &path,const std::strin } void RemovableDriveManager::inspect_file(const std::string &path, const std::string &parent_path) { + //confirms if the file is removable drive and adds it to vector + //if not same file system - could be removable drive if(!compare_filesystem_id(path, parent_path)) { @@ -335,7 +350,8 @@ void RemovableDriveManager::eject_drive(const std::string &path) } } std::cout<<"Ejecting "<<(*it).name<<" from "<< correct_path<<"\n"; - +// there is no usable command in c++ so terminal command is used instead +// but neither triggers "succesful safe removal messege" std::string command = ""; #if __APPLE__ command = "diskutil unmount "; diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index b4fc71e2656..ac1645df7bf 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -29,26 +29,34 @@ public: } RemovableDriveManager(RemovableDriveManager const&) = delete; void operator=(RemovableDriveManager const&) = delete; - - //update() searches for removable devices, returns false if empty. + //call only once. on apple register for unmnount callbacks. on windows register for device notification is prepared but not called (eject usb drive on widnows doesnt trigger the callback, sdc ard does), also enumerates devices for first time so init shoud be called on linux too. void init(); - bool update(const long time = 0,const bool check = false); //time = 0 is forced update, time expects wxGetLocalTime() + //update() searches for removable devices, returns false if empty. /time = 0 is forced update, time expects wxGetLocalTime() + bool update(const long time = 0,const bool check = false); bool is_drive_mounted(const std::string &path); void eject_drive(const std::string &path); + //returns path to last drive which was used, if none was used, returns device that was enumerated last std::string get_last_save_path(); + //returns path to last drive which was used, if none was used, returns empty string std::string get_drive_path(); std::vector get_all_drives(); bool is_path_on_removable_drive(const std::string &path); - void add_callback(std::function callback); // callback will notify only if device with last save path was removed - void erase_callbacks(); // erases all callbacks added by add_callback() + // callback will notify only if device with last save path was removed + void add_callback(std::function callback); + // erases all callbacks added by add_callback() + void erase_callbacks(); + // marks one of the eveices in vector as last used void set_last_save_path(const std::string &path); bool is_last_drive_removed(); - bool is_last_drive_removed_with_update(const long time = 0); // param as update() + // param as update() + bool is_last_drive_removed_with_update(const long time = 0); private: RemovableDriveManager(); void search_for_drives(); + //triggers callbacks if last used drive was removed void check_and_notify(); - std::string get_drive_from_path(const std::string& path);//returns drive path (same as path in DriveData) if exists otherwise empty string "" + //returns drive path (same as path in DriveData) if exists otherwise empty string "" + std::string get_drive_from_path(const std::string& path); void reset_last_save_path(); std::vector m_current_drives; @@ -58,8 +66,8 @@ private: std::string m_last_save_path; #if _WIN32 + //registers for notifications by creating invisible window void register_window(); - //INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); #else #if __APPLE__ RDMMMWrapper * m_rdmmm; @@ -69,7 +77,7 @@ private: void inspect_file(const std::string &path, const std::string &parent_path); #endif }; - +// apple wrapper for RemovableDriveManagerMM which searches for drives and/or ejects them #if __APPLE__ class RDMMMWrapper { From 6b7ebfb1311a6895517b63224a625d638950979f Mon Sep 17 00:00:00 2001 From: David Kocik Date: Fri, 13 Dec 2019 13:04:09 +0100 Subject: [PATCH 049/123] comments --- src/slic3r/GUI/Plater.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 417afa0a966..0dc09d9d816 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3517,7 +3517,7 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt) break; default: break; } - + //added to show disconnect_button after writing show_action_buttons(false); if (canceled) { From 0eb4d730c5fe6b60786b8030572754081fdbfd62 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 13 Dec 2019 13:23:55 +0100 Subject: [PATCH 050/123] Implemented rescaling for "Remove device" button --- src/slic3r/GUI/Plater.cpp | 58 ++++++++++++++++++--------------- src/slic3r/GUI/wxExtensions.cpp | 8 +++-- src/slic3r/GUI/wxExtensions.hpp | 7 ++++ 3 files changed, 44 insertions(+), 29 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 417afa0a966..814bcde0cfb 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -699,8 +699,8 @@ struct Sidebar::priv wxButton *btn_export_gcode; wxButton *btn_reslice; - wxButton *btn_send_gcode; - ScalableButton *btn_disconnect; + ScalableButton *btn_send_gcode; + ScalableButton *btn_remove_device; priv(Plater *plater) : plater(plater) {} ~priv(); @@ -849,25 +849,30 @@ Sidebar::Sidebar(Plater *parent) // Buttons underneath the scrolled area - auto init_btn = [this](wxButton **btn, wxString label, const std::string icon_name = "", wxString tooltip = wxEmptyString) { - *btn = new wxButton(this, wxID_ANY, label, wxDefaultPosition, - wxDefaultSize, wxBU_EXACTFIT); - (*btn)->SetFont(wxGetApp().bold_font()); - (*btn)->SetToolTip(tooltip); + // rescalable bitmap buttons "Send to printer" and "Remove device" - if (!icon_name.empty()) - (*btn)->SetBitmap(create_scaled_bitmap(this, icon_name)); + auto init_scalable_btn = [this](ScalableButton** btn, const std::string& icon_name, wxString tooltip = wxEmptyString) + { + ScalableBitmap bmp = ScalableBitmap(this, icon_name, int(2.5 * wxGetApp().em_unit())); + *btn = new ScalableButton(this, wxID_ANY, bmp, "", wxBU_EXACTFIT); + (*btn)->SetToolTip(tooltip); + (*btn)->Hide(); }; - init_btn(&p->btn_send_gcode, /*_(L("Send to printer"))*/"", "export_gcode", _(L("Send to printer"))); - p->btn_send_gcode->Hide(); - init_btn(&p->btn_export_gcode, _(L("Export G-code")) + dots); - init_btn(&p->btn_reslice, _(L("Slice now"))); + init_scalable_btn(&p->btn_send_gcode , "export_gcode", _(L("Send to printer"))); + init_scalable_btn(&p->btn_remove_device, "revert_all_" , _(L("Remove device"))); - p->btn_disconnect = new ScalableButton(this, wxID_ANY, "revert_all_", "", - wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT); - p->btn_disconnect->Hide(); - p->btn_disconnect->SetToolTip(_(L("Remove device"))); + // regular buttons "Slice now" and "Export G-code" + + const int scaled_height = p->btn_remove_device->GetBitmap().GetHeight() + 4; + auto init_btn = [this](wxButton **btn, wxString label, const int button_height) { + *btn = new wxButton(this, wxID_ANY, label, wxDefaultPosition, + wxSize(-1, button_height), wxBU_EXACTFIT); + (*btn)->SetFont(wxGetApp().bold_font()); + }; + + init_btn(&p->btn_export_gcode, _(L("Export G-code")) + dots , scaled_height); + init_btn(&p->btn_reslice , _(L("Slice now")) , scaled_height); enable_buttons(false); @@ -876,12 +881,10 @@ Sidebar::Sidebar(Plater *parent) auto* complect_btns_sizer = new wxBoxSizer(wxHORIZONTAL); complect_btns_sizer->Add(p->btn_export_gcode, 1, wxEXPAND); complect_btns_sizer->Add(p->btn_send_gcode, 0, wxEXPAND); - complect_btns_sizer->Add(p->btn_disconnect); + complect_btns_sizer->Add(p->btn_remove_device); btns_sizer->Add(p->btn_reslice, 0, wxEXPAND | wxTOP, margin_5); btns_sizer->Add(complect_btns_sizer, 0, wxEXPAND | wxTOP, margin_5); -// btns_sizer->Add(p->btn_send_gcode, 0, wxEXPAND | wxTOP, margin_5); -// btns_sizer->Add(p->btn_export_gcode, 0, wxEXPAND | wxTOP, margin_5); auto *sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(p->scrolled, 1, wxEXPAND); @@ -900,10 +903,7 @@ Sidebar::Sidebar(Plater *parent) p->plater->select_view_3D("Preview"); }); p->btn_send_gcode->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->send_gcode(); }); - p->btn_disconnect->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { - // #dk_FIXME - p->plater->eject_drive(); - }); + p->btn_remove_device->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->eject_drive(); }); } Sidebar::~Sidebar() {} @@ -1049,6 +1049,12 @@ void Sidebar::msw_rescale() p->object_info->msw_rescale(); + p->btn_send_gcode->msw_rescale(); + p->btn_remove_device->msw_rescale(); + const int scaled_height = p->btn_remove_device->GetBitmap().GetHeight() + 4; + p->btn_export_gcode->SetMinSize(wxSize(-1, scaled_height)); + p->btn_reslice ->SetMinSize(wxSize(-1, scaled_height)); + p->scrolled->Layout(); } @@ -1277,13 +1283,13 @@ void Sidebar::enable_buttons(bool enable) p->btn_reslice->Enable(enable); p->btn_export_gcode->Enable(enable); p->btn_send_gcode->Enable(enable); - p->btn_disconnect->Enable(enable); + p->btn_remove_device->Enable(enable); } bool Sidebar::show_reslice(bool show) const { return p->btn_reslice->Show(show); } bool Sidebar::show_export(bool show) const { return p->btn_export_gcode->Show(show); } bool Sidebar::show_send(bool show) const { return p->btn_send_gcode->Show(show); } -bool Sidebar::show_disconnect(bool show)const { return p->btn_disconnect->Show(show); } +bool Sidebar::show_disconnect(bool show)const { return p->btn_remove_device->Show(show); } bool Sidebar::is_multifilament() { diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 8493138971d..735e704ee88 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -3935,8 +3935,10 @@ ScalableButton::ScalableButton( wxWindow * parent, const ScalableBitmap& bitmap, const wxString& label /*= wxEmptyString*/, long style /*= wxBU_EXACTFIT | wxNO_BORDER*/) : + m_parent(parent), m_current_icon_name(bitmap.name()), - m_parent(parent) + m_px_cnt(bitmap.px_cnt()), + m_is_horizontal(bitmap.is_horizontal()) { Create(parent, id, label, wxDefaultPosition, wxDefaultSize, style); #ifdef __WXMSW__ @@ -3961,9 +3963,9 @@ void ScalableButton::SetBitmapDisabled_(const ScalableBitmap& bmp) void ScalableButton::msw_rescale() { - SetBitmap(create_scaled_bitmap(m_parent, m_current_icon_name)); + SetBitmap(create_scaled_bitmap(m_parent, m_current_icon_name, m_px_cnt, m_is_horizontal)); if (!m_disabled_icon_name.empty()) - SetBitmapDisabled(create_scaled_bitmap(m_parent, m_disabled_icon_name)); + SetBitmapDisabled(create_scaled_bitmap(m_parent, m_disabled_icon_name, m_px_cnt, m_is_horizontal)); if (m_width > 0 || m_height>0) { diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 7841b62feea..951f7ea8f45 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -729,6 +729,9 @@ public: wxBitmap& bmp() { return m_bmp; } const std::string& name() const{ return m_icon_name; } + int px_cnt()const {return m_px_cnt;} + bool is_horizontal()const {return m_is_horizontal;} + private: wxWindow* m_parent{ nullptr }; wxBitmap m_bmp = wxBitmap(); @@ -1116,6 +1119,10 @@ private: std::string m_disabled_icon_name = ""; int m_width {-1}; // should be multiplied to em_unit int m_height{-1}; // should be multiplied to em_unit + + // bitmap dimensions + int m_px_cnt{ 16 }; + bool m_is_horizontal{ false }; }; From 2016b283fb503b02730eda633f6a7ded9fced1b4 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 26 Nov 2019 14:19:29 +0100 Subject: [PATCH 051/123] removable drive manager - Windows part --- src/slic3r/GUI/AppConfig.cpp | 5 + src/slic3r/GUI/RemovableDriveManager.cpp | 149 +++++++++++++++++++++++ src/slic3r/GUI/RemovableDriveManager.hpp | 41 +++++++ 3 files changed, 195 insertions(+) create mode 100644 src/slic3r/GUI/RemovableDriveManager.cpp create mode 100644 src/slic3r/GUI/RemovableDriveManager.hpp diff --git a/src/slic3r/GUI/AppConfig.cpp b/src/slic3r/GUI/AppConfig.cpp index d33d945efb9..4f3272e264f 100644 --- a/src/slic3r/GUI/AppConfig.cpp +++ b/src/slic3r/GUI/AppConfig.cpp @@ -21,6 +21,7 @@ #include #include "I18N.hpp" +#include "RemovableDriveManager.hpp" namespace Slic3r { @@ -357,6 +358,10 @@ void AppConfig::update_skein_dir(const std::string &dir) std::string AppConfig::get_last_output_dir(const std::string &alt) const { + if (GUI::RemovableDriveManager::getInstance().update()) + { + return GUI::RemovableDriveManager::getInstance().getLastDrivePath(); + } const auto it = m_storage.find(""); if (it != m_storage.end()) { const auto it2 = it->second.find("last_output_path"); diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp new file mode 100644 index 00000000000..44d4181d1b2 --- /dev/null +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -0,0 +1,149 @@ +#include "RemovableDriveManager.hpp" + +#include +#include +#include +#include + +//#include +//#include "libslic3r/Utils.hpp" + +DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, + 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED); + +namespace Slic3r { +namespace GUI { + +std::vector RemovableDriveManager::currentDrives; + +bool RemovableDriveManager::update() +{ + searchForDrives(currentDrives); + return !currentDrives.empty(); +} +void RemovableDriveManager::searchForDrives(std::vector& newDrives) +{ + newDrives.clear(); + newDrives.reserve(26); + DWORD drivesMask = GetLogicalDrives(); + for (size_t i = 0; i < 26; i++) + { + if(drivesMask & (1 << i)) + { + std::string path (1,(char)('A' + i)); + path+=":"; + UINT driveType = GetDriveTypeA(path.c_str()); + //std::cout << "found drive" << (char)('A' + i) << ": type:" < 0) + { + newDrives.push_back(DriveData(volumeName, path)); + } + } + } + } + else if(driveType == 3)//disks and usb drives + { + } + } + } + +} + +void RemovableDriveManager::updateCurrentDrives(const std::vector& newDrives) +{ + currentDrives.clear(); + currentDrives.reserve(26); + for (auto it = newDrives.begin(); it != newDrives.end(); ++it) + { + currentDrives.push_back(*it); + } +} +void RemovableDriveManager::printDrivesToLog() +{ + //std::cout<<"current drives:"<< currentDrives.size() <<"\n"; + for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + { + //BOOST_LOG_TRIVIAL(trace) << boost::format("found disk %1%:") % ('A' + i); + //std::cout << /*std::string((*it).name.begin(), (*it).name.end()) << "(" << */(*it).path << ":/, "; + } + //std::cout << "\n"; +} +bool RemovableDriveManager::isDriveMounted(std::string path) +{ + for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + { + if ((*it).path == path) + { + return true; + } + } + return false; +} +void RemovableDriveManager::ejectDrive(std::string path) +{ + if (!update() || !isDriveMounted(path)) + return; + + path = "\\\\.\\"+path; + HANDLE handle = CreateFileA(path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); + if(handle == INVALID_HANDLE_VALUE) + { + std::cerr << "Ejecting " << path << " failed " << GetLastError() << " \n"; + return; + } + DWORD deviceControlRetVal(0); + BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0,nullptr , 0, &deviceControlRetVal, nullptr); + CloseHandle(handle); + if(error != 0) + std::cout << "Ejected " << path << "\n"; + else + std::cerr << "Ejecting " << path << " failed "<< deviceControlRetVal << " " << GetLastError() <<" \n"; + + for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + { + if ((*it).path == path) + { + currentDrives.erase(it); + break; + } + } +} +std::string RemovableDriveManager::getLastDrivePath() +{ + if (!currentDrives.empty()) + { + return currentDrives.back().path; + } + return ""; +} +void RemovableDriveManager::getAllDrives(std::vector& drives) +{ + drives.clear(); + drives.reserve(26); + for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + { + drives.push_back(*it); + } +} +}} \ No newline at end of file diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp new file mode 100644 index 00000000000..cab58fee6c8 --- /dev/null +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -0,0 +1,41 @@ +#ifndef slic3r_GUI_RemovableDriveManager_hpp_ +#define slic3r_GUI_RemovableDriveManager_hpp_ + +#include +#include + +namespace Slic3r { +namespace GUI { +struct DriveData +{ + std::wstring name; + std::string path; + DriveData(std::wstring n, std::string p):name(n),path(p){} +}; +class RemovableDriveManager +{ +public: + static RemovableDriveManager& getInstance() + { + static RemovableDriveManager instance; + return instance; + } + RemovableDriveManager(RemovableDriveManager const&) = delete; + void operator=(RemovableDriveManager const&) = delete; + + //update() searches for removable devices, returns false if empty. + static bool update(); + static bool isDriveMounted(std::string path); + static void ejectDrive(std::string path); + static std::string getLastDrivePath(); + static void getAllDrives(std::vector& drives); +private: + RemovableDriveManager(){} + static void searchForDrives(std::vector& newDrives); + static void printDrivesToLog(); + static void updateCurrentDrives(const std::vector& newDrives); + static std::vector currentDrives; + +}; +}} +#endif \ No newline at end of file From aa59111c1c4de5be7a61e66d28b3bd6d343da241 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 26 Nov 2019 15:52:18 +0100 Subject: [PATCH 052/123] removable drives manager linux part --- src/slic3r/CMakeLists.txt | 2 + src/slic3r/GUI/RemovableDriveManager.cpp | 166 +++++++++++++++++------ src/slic3r/GUI/RemovableDriveManager.hpp | 10 +- 3 files changed, 134 insertions(+), 44 deletions(-) diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index bcddcfe0697..2d7b99b73d4 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -111,6 +111,8 @@ set(SLIC3R_GUI_SOURCES GUI/WipeTowerDialog.hpp GUI/RammingChart.cpp GUI/RammingChart.hpp + GUI/RemovableDriveManager.cpp + GUI/RemovableDriveManager.hpp GUI/BonjourDialog.cpp GUI/BonjourDialog.hpp GUI/ButtonsDescription.cpp diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 44d4181d1b2..ae718b7d3a8 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -1,26 +1,34 @@ #include "RemovableDriveManager.hpp" -#include -#include + + #include #include -//#include -//#include "libslic3r/Utils.hpp" +#if _WIN32 +#include +#include DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED); +#else +//linux includes +#include +#include +#include +#include +#include +#endif namespace Slic3r { namespace GUI { std::vector RemovableDriveManager::currentDrives; -bool RemovableDriveManager::update() -{ - searchForDrives(currentDrives); - return !currentDrives.empty(); -} + + + +#if _WIN32 void RemovableDriveManager::searchForDrives(std::vector& newDrives) { newDrives.clear(); @@ -69,37 +77,6 @@ void RemovableDriveManager::searchForDrives(std::vector& newDrives) } } - -void RemovableDriveManager::updateCurrentDrives(const std::vector& newDrives) -{ - currentDrives.clear(); - currentDrives.reserve(26); - for (auto it = newDrives.begin(); it != newDrives.end(); ++it) - { - currentDrives.push_back(*it); - } -} -void RemovableDriveManager::printDrivesToLog() -{ - //std::cout<<"current drives:"<< currentDrives.size() <<"\n"; - for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) - { - //BOOST_LOG_TRIVIAL(trace) << boost::format("found disk %1%:") % ('A' + i); - //std::cout << /*std::string((*it).name.begin(), (*it).name.end()) << "(" << */(*it).path << ":/, "; - } - //std::cout << "\n"; -} -bool RemovableDriveManager::isDriveMounted(std::string path) -{ - for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) - { - if ((*it).path == path) - { - return true; - } - } - return false; -} void RemovableDriveManager::ejectDrive(std::string path) { if (!update() || !isDriveMounted(path)) @@ -129,6 +106,115 @@ void RemovableDriveManager::ejectDrive(std::string path) } } } +#else +void RemovableDriveManager::searchForDrives(std::vector& newDrives) +{ + struct stat buf; + std::string path(std::getenv("USER")); + std::string pp(path); + + newDrives.clear(); + newDrives.reserve(26); + + //search /media/* folder + stat("/media/",&buf); + std::cout << "/media ID: " <& newDrives,const std::string path, const dev_t parentDevID) +{ + glob_t globbuf; + globbuf.gl_offs = 2; + std::cout<<"searching "<& newDrives) +{ + currentDrives.clear(); + currentDrives.reserve(26); + for (auto it = newDrives.begin(); it != newDrives.end(); ++it) + { + currentDrives.push_back(*it); + } +} +bool RemovableDriveManager::isDriveMounted(std::string path) +{ + for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + { + if ((*it).path == path) + { + return true; + } + } + return false; +} + std::string RemovableDriveManager::getLastDrivePath() { if (!currentDrives.empty()) diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index cab58fee6c8..c503fdf1873 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -8,9 +8,9 @@ namespace Slic3r { namespace GUI { struct DriveData { - std::wstring name; + std::string name; std::string path; - DriveData(std::wstring n, std::string p):name(n),path(p){} + DriveData(std::string n, std::string p):name(n),path(p){} }; class RemovableDriveManager { @@ -32,10 +32,12 @@ public: private: RemovableDriveManager(){} static void searchForDrives(std::vector& newDrives); - static void printDrivesToLog(); static void updateCurrentDrives(const std::vector& newDrives); static std::vector currentDrives; - +#if _WIN32 +#else + static void searchPath(std::vector& newDrives,const std::string path, const dev_t parentDevID); +#endif }; }} #endif \ No newline at end of file From 3c1060d99b04bb166340d23d2c7bfaf66028bedb Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 27 Nov 2019 11:33:36 +0100 Subject: [PATCH 053/123] refactoring --- src/slic3r/GUI/AppConfig.cpp | 2 +- src/slic3r/GUI/RemovableDriveManager.cpp | 116 ++++++++++------------- src/slic3r/GUI/RemovableDriveManager.hpp | 15 ++- 3 files changed, 58 insertions(+), 75 deletions(-) diff --git a/src/slic3r/GUI/AppConfig.cpp b/src/slic3r/GUI/AppConfig.cpp index 4f3272e264f..26ca07082d1 100644 --- a/src/slic3r/GUI/AppConfig.cpp +++ b/src/slic3r/GUI/AppConfig.cpp @@ -360,7 +360,7 @@ std::string AppConfig::get_last_output_dir(const std::string &alt) const { if (GUI::RemovableDriveManager::getInstance().update()) { - return GUI::RemovableDriveManager::getInstance().getLastDrivePath(); + return GUI::RemovableDriveManager::getInstance().get_last_drive_path(); } const auto it = m_storage.find(""); if (it != m_storage.end()) { diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index ae718b7d3a8..53515ccdcba 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -1,14 +1,12 @@ #include "RemovableDriveManager.hpp" - - - #include #include - +#include "boost/nowide/convert.hpp" #if _WIN32 #include #include +#include DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED); #else @@ -23,16 +21,13 @@ DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, namespace Slic3r { namespace GUI { -std::vector RemovableDriveManager::currentDrives; - - - +std::vector RemovableDriveManager::m_current_drives; #if _WIN32 -void RemovableDriveManager::searchForDrives(std::vector& newDrives) +void RemovableDriveManager::search_for_drives() { - newDrives.clear(); - newDrives.reserve(26); + m_current_drives.clear(); + m_current_drives.reserve(26); DWORD drivesMask = GetLogicalDrives(); for (size_t i = 0; i < 26; i++) { @@ -65,7 +60,7 @@ void RemovableDriveManager::searchForDrives(std::vector& newDrives) //std::cout << std::string(volumeName.begin(), volumeName.end()) << " " << std::string(fileSystemName.begin(), fileSystemName.end()) << " " << freeSpace.QuadPart << "\n"; if (freeSpace.QuadPart > 0) { - newDrives.push_back(DriveData(volumeName, path)); + m_current_drives.push_back(DriveData(boost::nowide::narrow(volumeName), path)); } } } @@ -77,49 +72,51 @@ void RemovableDriveManager::searchForDrives(std::vector& newDrives) } } -void RemovableDriveManager::ejectDrive(std::string path) +void RemovableDriveManager::eject_drive(const std::string &path) { - if (!update() || !isDriveMounted(path)) - return; - path = "\\\\.\\"+path; - HANDLE handle = CreateFileA(path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); - if(handle == INVALID_HANDLE_VALUE) - { - std::cerr << "Ejecting " << path << " failed " << GetLastError() << " \n"; + //if (!update() || !is_drive_mounted(path)) + if(m_current_drives.empty()) return; - } - DWORD deviceControlRetVal(0); - BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0,nullptr , 0, &deviceControlRetVal, nullptr); - CloseHandle(handle); - if(error != 0) - std::cout << "Ejected " << path << "\n"; - else - std::cerr << "Ejecting " << path << " failed "<< deviceControlRetVal << " " << GetLastError() <<" \n"; - - for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) { if ((*it).path == path) { - currentDrives.erase(it); + std::string mpath = "\\\\.\\" + path; + HANDLE handle = CreateFileA(mpath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); + if (handle == INVALID_HANDLE_VALUE) + { + std::cerr << "Ejecting " << mpath << " failed " << GetLastError() << " \n"; + return; + } + DWORD deviceControlRetVal(0); + BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); + CloseHandle(handle); + if (error != 0) + std::cout << "Ejected " << mpath << "\n"; + else + std::cerr << "Ejecting " << mpath << " failed " << deviceControlRetVal << " " << GetLastError() << " \n"; + + + m_current_drives.erase(it); break; } } } #else -void RemovableDriveManager::searchForDrives(std::vector& newDrives) +void RemovableDriveManager::search_for_drives() { struct stat buf; std::string path(std::getenv("USER")); std::string pp(path); - newDrives.clear(); - newDrives.reserve(26); + m_current_drives.clear(); + m_current_Drives.reserve(26); //search /media/* folder stat("/media/",&buf); std::cout << "/media ID: " <& newDrives) stat(pp.c_str() ,&buf); std::cout << pp <<" ID: " <& newDrives,const std::string path, const dev_t parentDevID) +void RemovableDriveManager::search_path(const std::string &path,const dev_t &parentDevID) { glob_t globbuf; globbuf.gl_offs = 2; @@ -159,17 +156,17 @@ void RemovableDriveManager::searchPath(std::vector& newDrives,const s std::cout << buf.st_dev << "\n"; if(buf.st_dev != parentDevID)// not same file system { - newDrives.push_back(DriveData(name,globbuf.gl_pathv[i])); + m_current_drives.push_back(DriveData(name,globbuf.gl_pathv[i])); } } globfree(&globbuf); } -void RemovableDriveManager::ejectDrive(std::string path) +void RemovableDriveManager::eject_drive(const std::string &path) { - if (currentDrives.empty()) + if (m_current_drives.empty()) return; - for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) { if((*it).path == path) { @@ -180,7 +177,7 @@ void RemovableDriveManager::ejectDrive(std::string path) int errsv = errno; std::cerr<<"Ejecting failed Error "<< errsv<<"\n"; } - currentDrives.erase(it); + m_current_drives.erase(it); break; } @@ -190,22 +187,14 @@ void RemovableDriveManager::ejectDrive(std::string path) #endif bool RemovableDriveManager::update() { - searchForDrives(currentDrives); - return !currentDrives.empty(); + search_for_drives(); + return !m_current_drives.empty(); } -void RemovableDriveManager::updateCurrentDrives(const std::vector& newDrives) + +bool RemovableDriveManager::is_drive_mounted(const std::string &path) { - currentDrives.clear(); - currentDrives.reserve(26); - for (auto it = newDrives.begin(); it != newDrives.end(); ++it) - { - currentDrives.push_back(*it); - } -} -bool RemovableDriveManager::isDriveMounted(std::string path) -{ - for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) { if ((*it).path == path) { @@ -215,21 +204,16 @@ bool RemovableDriveManager::isDriveMounted(std::string path) return false; } -std::string RemovableDriveManager::getLastDrivePath() +std::string RemovableDriveManager::get_last_drive_path() { - if (!currentDrives.empty()) + if (!m_current_drives.empty()) { - return currentDrives.back().path; + return m_current_drives.back().path; } return ""; } -void RemovableDriveManager::getAllDrives(std::vector& drives) +std::vector RemovableDriveManager::get_all_drives() { - drives.clear(); - drives.reserve(26); - for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) - { - drives.push_back(*it); - } + return m_current_drives; } }} \ No newline at end of file diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index c503fdf1873..8270c0f0fba 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -25,18 +25,17 @@ public: //update() searches for removable devices, returns false if empty. static bool update(); - static bool isDriveMounted(std::string path); - static void ejectDrive(std::string path); - static std::string getLastDrivePath(); - static void getAllDrives(std::vector& drives); + static bool is_drive_mounted(const std::string &path); + static void eject_drive(const std::string &path); + static std::string get_last_drive_path(); + static std::vector get_all_drives(); private: RemovableDriveManager(){} - static void searchForDrives(std::vector& newDrives); - static void updateCurrentDrives(const std::vector& newDrives); - static std::vector currentDrives; + static void search_for_drives(); + static std::vector m_current_drives; #if _WIN32 #else - static void searchPath(std::vector& newDrives,const std::string path, const dev_t parentDevID); + static void search_path(const std::string &path, const dev_t &parentDevID); #endif }; }} From c409732d012df682664765168bf8221cf0bdb1c5 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 27 Nov 2019 13:30:45 +0100 Subject: [PATCH 054/123] check if last path is on rem drive --- src/slic3r/GUI/AppConfig.cpp | 6 +---- src/slic3r/GUI/Plater.cpp | 9 ++++++- src/slic3r/GUI/RemovableDriveManager.cpp | 30 +++++++++++++++++++++++- src/slic3r/GUI/RemovableDriveManager.hpp | 1 + 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/slic3r/GUI/AppConfig.cpp b/src/slic3r/GUI/AppConfig.cpp index 26ca07082d1..70558225135 100644 --- a/src/slic3r/GUI/AppConfig.cpp +++ b/src/slic3r/GUI/AppConfig.cpp @@ -21,7 +21,6 @@ #include #include "I18N.hpp" -#include "RemovableDriveManager.hpp" namespace Slic3r { @@ -358,10 +357,7 @@ void AppConfig::update_skein_dir(const std::string &dir) std::string AppConfig::get_last_output_dir(const std::string &alt) const { - if (GUI::RemovableDriveManager::getInstance().update()) - { - return GUI::RemovableDriveManager::getInstance().get_last_drive_path(); - } + const auto it = m_storage.find(""); if (it != m_storage.end()) { const auto it2 = it->second.find("last_output_path"); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index c8267331d32..efe0ab7b314 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -77,6 +77,7 @@ #include "../Utils/FixModelByWin10.hpp" #include "../Utils/UndoRedo.hpp" #include "../Utils/Thread.hpp" +#include "RemovableDriveManager.hpp" #include // Needs to be last because reasons :-/ #include "WipeTowerDialog.hpp" @@ -4661,7 +4662,13 @@ void Plater::export_gcode() } default_output_file = fs::path(Slic3r::fold_utf8_to_ascii(default_output_file.string())); auto start_dir = wxGetApp().app_config->get_last_output_dir(default_output_file.parent_path().string()); - + if (GUI::RemovableDriveManager::getInstance().update()) + { + if (!RemovableDriveManager::getInstance().is_path_on_removable_drive(start_dir)) + { + start_dir = RemovableDriveManager::getInstance().get_last_drive_path(); + } + } wxFileDialog dlg(this, (printer_technology() == ptFFF) ? _(L("Save G-code file as:")) : _(L("Save SL1 file as:")), start_dir, from_path(default_output_file.filename()), diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 53515ccdcba..776334bf22c 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -7,6 +7,7 @@ #include #include #include +#include DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED); #else @@ -208,7 +209,11 @@ std::string RemovableDriveManager::get_last_drive_path() { if (!m_current_drives.empty()) { +#if _WIN32 + return m_current_drives.back().path + "\\"; +#else return m_current_drives.back().path; +#endif } return ""; } @@ -216,4 +221,27 @@ std::vector RemovableDriveManager::get_all_drives() { return m_current_drives; } -}} \ No newline at end of file +#if _WIN32 +bool RemovableDriveManager::is_path_on_removable_drive(const std::string& path) +{ + if (m_current_drives.empty()) + return false; + int letter = PathGetDriveNumberA(path.c_str()); + for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) + { + char drive = (*it).path[0]; + if (drive == ('A' + letter)) + return true; + } + return false; +} +#else +bool RemovableDriveManager::is_path_on_removable_drive(const std::string& path, const std::string& drive) +{ + if (m_current_drives.empty()) + return false; + + return false; +} +#endif +}}//namespace Slicer::Gui:: \ No newline at end of file diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 8270c0f0fba..3de9d72cee7 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -29,6 +29,7 @@ public: static void eject_drive(const std::string &path); static std::string get_last_drive_path(); static std::vector get_all_drives(); + static bool is_path_on_removable_drive(const std::string &path); private: RemovableDriveManager(){} static void search_for_drives(); From 371f1428f8b72d00711e10d23da78aeaeb780db7 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 27 Nov 2019 14:30:10 +0100 Subject: [PATCH 055/123] prev commit linux part --- src/slic3r/GUI/RemovableDriveManager.cpp | 139 ++++++++++++----------- 1 file changed, 75 insertions(+), 64 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 776334bf22c..2d1f4ba6f2e 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -29,46 +29,43 @@ void RemovableDriveManager::search_for_drives() { m_current_drives.clear(); m_current_drives.reserve(26); - DWORD drivesMask = GetLogicalDrives(); + DWORD drives_mask = GetLogicalDrives(); for (size_t i = 0; i < 26; i++) { - if(drivesMask & (1 << i)) + if(drives_mask & (1 << i)) { std::string path (1,(char)('A' + i)); path+=":"; - UINT driveType = GetDriveTypeA(path.c_str()); + UINT drive_type = GetDriveTypeA(path.c_str()); //std::cout << "found drive" << (char)('A' + i) << ": type:" < 0) + if (free_space.QuadPart > 0) { - m_current_drives.push_back(DriveData(boost::nowide::narrow(volumeName), path)); + m_current_drives.push_back(DriveData(boost::nowide::narrow(volume_name), path)); } } } } - else if(driveType == 3)//disks and usb drives - { - } } } @@ -93,10 +90,10 @@ void RemovableDriveManager::eject_drive(const std::string &path) DWORD deviceControlRetVal(0); BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); CloseHandle(handle); - if (error != 0) - std::cout << "Ejected " << mpath << "\n"; - else + if (error == 0) + { std::cerr << "Ejecting " << mpath << " failed " << deviceControlRetVal << " " << GetLastError() << " \n"; + } m_current_drives.erase(it); @@ -104,6 +101,19 @@ void RemovableDriveManager::eject_drive(const std::string &path) } } } +bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path) +{ + if (m_current_drives.empty()) + return false; + int letter = PathGetDriveNumberA(path.c_str()); + for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) + { + char drive = (*it).path[0]; + if (drive == ('A' + letter)) + return true; + } + return false; +} #else void RemovableDriveManager::search_for_drives() { @@ -112,11 +122,11 @@ void RemovableDriveManager::search_for_drives() std::string pp(path); m_current_drives.clear(); - m_current_Drives.reserve(26); + m_current_drives.reserve(26); //search /media/* folder stat("/media/",&buf); - std::cout << "/media ID: " < RemovableDriveManager::get_all_drives() return m_current_drives; } #if _WIN32 -bool RemovableDriveManager::is_path_on_removable_drive(const std::string& path) -{ - if (m_current_drives.empty()) - return false; - int letter = PathGetDriveNumberA(path.c_str()); - for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) - { - char drive = (*it).path[0]; - if (drive == ('A' + letter)) - return true; - } - return false; -} -#else -bool RemovableDriveManager::is_path_on_removable_drive(const std::string& path, const std::string& drive) -{ - if (m_current_drives.empty()) - return false; - return false; -} +#else + #endif }}//namespace Slicer::Gui:: \ No newline at end of file From 994b2d16eb4e7762c6abfe2d7f3529712334b4bc Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 27 Nov 2019 15:47:37 +0100 Subject: [PATCH 056/123] rdm update every 2 seconds --- src/slic3r/GUI/GUI_App.cpp | 2 ++ src/slic3r/GUI/RemovableDriveManager.cpp | 15 ++++++++++++++- src/slic3r/GUI/RemovableDriveManager.hpp | 3 ++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index e02dd5f6e75..3d09e3573bb 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -46,6 +46,7 @@ #include "SysInfoDialog.hpp" #include "KBShortcutsDialog.hpp" #include "UpdateDialogs.hpp" +#include "RemovableDriveManager.hpp" #ifdef __WXMSW__ #include @@ -271,6 +272,7 @@ bool GUI_App::on_init_inner() this->obj_manipul()->update_if_dirty(); + RemovableDriveManager::getInstance().update(wxGetLocalTime()); // Preset updating & Configwizard are done after the above initializations, // and after MainFrame is created & shown. // The extra CallAfter() is needed because of Mac, where this is the only way diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 2d1f4ba6f2e..235e1ccbe84 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -23,6 +23,7 @@ namespace Slic3r { namespace GUI { std::vector RemovableDriveManager::m_current_drives; +long RemovableDriveManager::m_last_update = 0; #if _WIN32 void RemovableDriveManager::search_for_drives() @@ -215,8 +216,20 @@ bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path) return false; } #endif -bool RemovableDriveManager::update() +bool RemovableDriveManager::update(long time) { + if(time != 0) //time = 0 is forced update + { + long diff = m_last_update - time; + if(diff <= -2) + { + m_last_update = time; + }else + { + return false; // return value shouldnt matter if update didnt run + } + } + std::cout << "RDM update " << m_last_update <<"\n"; search_for_drives(); return !m_current_drives.empty(); } diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 3de9d72cee7..c83b8033c98 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -24,7 +24,7 @@ public: void operator=(RemovableDriveManager const&) = delete; //update() searches for removable devices, returns false if empty. - static bool update(); + static bool update(long time = 0); //time = 0 is forced update static bool is_drive_mounted(const std::string &path); static void eject_drive(const std::string &path); static std::string get_last_drive_path(); @@ -34,6 +34,7 @@ private: RemovableDriveManager(){} static void search_for_drives(); static std::vector m_current_drives; + static long m_last_update; #if _WIN32 #else static void search_path(const std::string &path, const dev_t &parentDevID); From 77d100e9017698bc88eac76177aff0a8a27d608e Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 28 Nov 2019 13:38:08 +0100 Subject: [PATCH 057/123] add_callback function --- src/slic3r/GUI/RemovableDriveManager.cpp | 65 ++++++++++++++++++++---- src/slic3r/GUI/RemovableDriveManager.hpp | 6 ++- 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 235e1ccbe84..a1a5d7dd927 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -23,7 +23,8 @@ namespace Slic3r { namespace GUI { std::vector RemovableDriveManager::m_current_drives; -long RemovableDriveManager::m_last_update = 0; +std::vector> RemovableDriveManager::m_callbacks; + #if _WIN32 void RemovableDriveManager::search_for_drives() @@ -69,7 +70,7 @@ void RemovableDriveManager::search_for_drives() } } } - + //std::cout << "found drives:" << m_current_drives.size() << "\n"; } void RemovableDriveManager::eject_drive(const std::string &path) { @@ -115,6 +116,25 @@ bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path) } return false; } +void RemovableDriveManager::register_window() +{ + /* + WNDCLASSEX wndClass; + + wndClass.cbSize = sizeof(WNDCLASSEX); + wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; + wndClass.hInstance = reinterpret_cast(GetModuleHandle(0)); + wndClass.lpfnWndProc = reinterpret_cast(WinProcCallback); + wndClass.cbClsExtra = 0; + wndClass.cbWndExtra = 0; + wndClass.hIcon = LoadIcon(0, IDI_APPLICATION); + wndClass.hbrBackground = CreateSolidBrush(RGB(192, 192, 192)); + wndClass.hCursor = LoadCursor(0, IDC_ARROW); + wndClass.lpszClassName = L"SlicerWindowClass"; + wndClass.lpszMenuName = NULL; + wndClass.hIconSm = wndClass.hIcon; + */ +} #else void RemovableDriveManager::search_for_drives() { @@ -218,19 +238,29 @@ bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path) #endif bool RemovableDriveManager::update(long time) { + static long last_update = 0; + if(last_update == 0) + { + //add_callback(std::bind(&RemovableDriveManager::print, RemovableDriveManager::getInstance())); + add_callback([](void) { print(); }); +#if _WIN32 + register_window(); +#endif + } if(time != 0) //time = 0 is forced update { - long diff = m_last_update - time; + long diff = last_update - time; if(diff <= -2) { - m_last_update = time; + last_update = time; }else { return false; // return value shouldnt matter if update didnt run } } - std::cout << "RDM update " << m_last_update <<"\n"; + //std::cout << "RDM update " << last_update <<"\n"; search_for_drives(); + check_and_notify(); return !m_current_drives.empty(); } @@ -263,9 +293,24 @@ std::vector RemovableDriveManager::get_all_drives() { return m_current_drives; } -#if _WIN32 - -#else - -#endif +void RemovableDriveManager::check_and_notify() +{ + static int number_of_drives = 0; + if(number_of_drives != m_current_drives.size()) + { + for (auto it = m_callbacks.begin(); it != m_callbacks.end(); ++it) + { + (*it)(); + } + number_of_drives = m_current_drives.size(); + } +} +void RemovableDriveManager::add_callback(std::function callback) +{ + m_callbacks.push_back(callback); +} +void RemovableDriveManager::print() +{ + std::cout << "notified\n"; +} }}//namespace Slicer::Gui:: \ No newline at end of file diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index c83b8033c98..9f3ebf326b1 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -30,12 +30,16 @@ public: static std::string get_last_drive_path(); static std::vector get_all_drives(); static bool is_path_on_removable_drive(const std::string &path); + static void add_callback(std::function callback); + static void print(); private: RemovableDriveManager(){} static void search_for_drives(); + static void check_and_notify(); static std::vector m_current_drives; - static long m_last_update; + static std::vector> m_callbacks; #if _WIN32 + static void register_window(); #else static void search_path(const std::string &path, const dev_t &parentDevID); #endif From 9c3a84c0f7c2607827a7a51a0a0a58be423dc067 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 28 Nov 2019 13:50:58 +0100 Subject: [PATCH 058/123] refactoring --- src/slic3r/GUI/GUI_App.cpp | 2 +- src/slic3r/GUI/Plater.cpp | 6 ++--- src/slic3r/GUI/RemovableDriveManager.cpp | 6 ++--- src/slic3r/GUI/RemovableDriveManager.hpp | 30 ++++++++++++------------ 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 3d09e3573bb..e33fc0d2e51 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -272,7 +272,7 @@ bool GUI_App::on_init_inner() this->obj_manipul()->update_if_dirty(); - RemovableDriveManager::getInstance().update(wxGetLocalTime()); + RemovableDriveManager::get_instance().update(wxGetLocalTime()); // Preset updating & Configwizard are done after the above initializations, // and after MainFrame is created & shown. // The extra CallAfter() is needed because of Mac, where this is the only way diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index efe0ab7b314..3e3827926fc 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4662,11 +4662,11 @@ void Plater::export_gcode() } default_output_file = fs::path(Slic3r::fold_utf8_to_ascii(default_output_file.string())); auto start_dir = wxGetApp().app_config->get_last_output_dir(default_output_file.parent_path().string()); - if (GUI::RemovableDriveManager::getInstance().update()) + if (GUI::RemovableDriveManager::get_instance().update()) { - if (!RemovableDriveManager::getInstance().is_path_on_removable_drive(start_dir)) + if (!RemovableDriveManager::get_instance().is_path_on_removable_drive(start_dir)) { - start_dir = RemovableDriveManager::getInstance().get_last_drive_path(); + start_dir = RemovableDriveManager::get_instance().get_last_drive_path(); } } wxFileDialog dlg(this, (printer_technology() == ptFFF) ? _(L("Save G-code file as:")) : _(L("Save SL1 file as:")), diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index a1a5d7dd927..777085165de 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -22,8 +22,8 @@ DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, namespace Slic3r { namespace GUI { -std::vector RemovableDriveManager::m_current_drives; -std::vector> RemovableDriveManager::m_callbacks; +//std::vector RemovableDriveManager::m_current_drives; +//std::vector> RemovableDriveManager::m_callbacks; #if _WIN32 @@ -242,7 +242,7 @@ bool RemovableDriveManager::update(long time) if(last_update == 0) { //add_callback(std::bind(&RemovableDriveManager::print, RemovableDriveManager::getInstance())); - add_callback([](void) { print(); }); + add_callback([](void) { RemovableDriveManager::get_instance().print(); }); #if _WIN32 register_window(); #endif diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 9f3ebf326b1..f3abc420739 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -15,7 +15,7 @@ struct DriveData class RemovableDriveManager { public: - static RemovableDriveManager& getInstance() + static RemovableDriveManager& get_instance() { static RemovableDriveManager instance; return instance; @@ -24,24 +24,24 @@ public: void operator=(RemovableDriveManager const&) = delete; //update() searches for removable devices, returns false if empty. - static bool update(long time = 0); //time = 0 is forced update - static bool is_drive_mounted(const std::string &path); - static void eject_drive(const std::string &path); - static std::string get_last_drive_path(); - static std::vector get_all_drives(); - static bool is_path_on_removable_drive(const std::string &path); - static void add_callback(std::function callback); - static void print(); + bool update(long time = 0); //time = 0 is forced update + bool is_drive_mounted(const std::string &path); + void eject_drive(const std::string &path); + std::string get_last_drive_path(); + std::vector get_all_drives(); + bool is_path_on_removable_drive(const std::string &path); + void add_callback(std::function callback); + void print(); private: RemovableDriveManager(){} - static void search_for_drives(); - static void check_and_notify(); - static std::vector m_current_drives; - static std::vector> m_callbacks; + void search_for_drives(); + void check_and_notify(); + std::vector m_current_drives; + std::vector> m_callbacks; #if _WIN32 - static void register_window(); + void register_window(); #else - static void search_path(const std::string &path, const dev_t &parentDevID); + void search_path(const std::string &path, const dev_t &parentDevID); #endif }; }} From 393ec50d0b39c54bcc8577c77089bfc4146bcfea Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 28 Nov 2019 16:35:22 +0100 Subject: [PATCH 059/123] search for rd as root --- src/slic3r/GUI/RemovableDriveManager.cpp | 103 +++++++++++++---------- src/slic3r/GUI/RemovableDriveManager.hpp | 3 +- 2 files changed, 61 insertions(+), 45 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 777085165de..4368d06b647 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -1,6 +1,5 @@ #include "RemovableDriveManager.hpp" #include -#include #include "boost/nowide/convert.hpp" #if _WIN32 @@ -17,6 +16,7 @@ DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, #include #include #include +#include #endif namespace Slic3r { @@ -96,8 +96,6 @@ void RemovableDriveManager::eject_drive(const std::string &path) { std::cerr << "Ejecting " << mpath << " failed " << deviceControlRetVal << " " << GetLastError() << " \n"; } - - m_current_drives.erase(it); break; } @@ -138,65 +136,85 @@ void RemovableDriveManager::register_window() #else void RemovableDriveManager::search_for_drives() { - struct stat buf; - std::string path(std::getenv("USER")); - std::string pp(path); - + m_current_drives.clear(); m_current_drives.reserve(26); //search /media/* folder - stat("/media/",&buf); - //std::cout << "/media ID: " <pw_name; + pp = path; + //search /media/USERNAME/* folder + pp = "/media/"+pp; + path = "/media/" + path + "/*"; + search_path(path, pp); - stat(pp.c_str() ,&buf); - //std::cout << pp <<" ID: " < RemovableDriveManager::get_all_drives() } void RemovableDriveManager::check_and_notify() { - static int number_of_drives = 0; + static size_t number_of_drives = 0; if(number_of_drives != m_current_drives.size()) { for (auto it = m_callbacks.begin(); it != m_callbacks.end(); ++it) diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index f3abc420739..43e47a08671 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -41,7 +41,8 @@ private: #if _WIN32 void register_window(); #else - void search_path(const std::string &path, const dev_t &parentDevID); + void search_path(const std::string &path, const std::string &parent_path); + bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); #endif }; }} From 1850952dfbcc1b71e27122cbd7ecd5ab3f45891e Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 3 Dec 2019 10:09:53 +0100 Subject: [PATCH 060/123] linux eject --- src/slic3r/GUI/GUI_App.cpp | 1 + src/slic3r/GUI/RemovableDriveManager.cpp | 29 ++++++++++++++---------- src/slic3r/GUI/RemovableDriveManager.hpp | 3 ++- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index e33fc0d2e51..e6c92cd0a8d 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -273,6 +273,7 @@ bool GUI_App::on_init_inner() this->obj_manipul()->update_if_dirty(); RemovableDriveManager::get_instance().update(wxGetLocalTime()); + // Preset updating & Configwizard are done after the above initializations, // and after MainFrame is created & shown. // The extra CallAfter() is needed because of Mac, where this is the only way diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 4368d06b647..ec730692fa2 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -20,8 +20,7 @@ DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, #endif namespace Slic3r { -namespace GUI { - +namespace GUI { //std::vector RemovableDriveManager::m_current_drives; //std::vector> RemovableDriveManager::m_callbacks; @@ -95,7 +94,10 @@ void RemovableDriveManager::eject_drive(const std::string &path) if (error == 0) { std::cerr << "Ejecting " << mpath << " failed " << deviceControlRetVal << " " << GetLastError() << " \n"; + return; } + + m_current_drives.erase(it); break; } @@ -179,7 +181,7 @@ void RemovableDriveManager::search_for_drives() } - std::cout << "found drives:" < RemovableDriveManager::get_all_drives() } void RemovableDriveManager::check_and_notify() { - static size_t number_of_drives = 0; - if(number_of_drives != m_current_drives.size()) + //std::cout<<"drives count: "< callback) { diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 43e47a08671..b465b1c1b81 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -33,11 +33,12 @@ public: void add_callback(std::function callback); void print(); private: - RemovableDriveManager(){} + RemovableDriveManager():m_drives_count(0){} void search_for_drives(); void check_and_notify(); std::vector m_current_drives; std::vector> m_callbacks; + size_t m_drives_count; #if _WIN32 void register_window(); #else From f4991bee3f1af274dc6bf313964b339801dde183 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 3 Dec 2019 10:55:38 +0100 Subject: [PATCH 061/123] windows paths --- src/slic3r/GUI/RemovableDriveManager.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index ec730692fa2..9b3020e79ef 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -62,6 +62,7 @@ void RemovableDriveManager::search_for_drives() //std::cout << std::string(volumeName.begin(), volumeName.end()) << " " << std::string(fileSystemName.begin(), fileSystemName.end()) << " " << freeSpace.QuadPart << "\n"; if (free_space.QuadPart > 0) { + path += "\\"; m_current_drives.push_back(DriveData(boost::nowide::narrow(volume_name), path)); } } @@ -82,6 +83,8 @@ void RemovableDriveManager::eject_drive(const std::string &path) if ((*it).path == path) { std::string mpath = "\\\\.\\" + path; + mpath = mpath.substr(0, mpath.size() - 1); + std::cout << "Ejecting " << mpath << "\n"; HANDLE handle = CreateFileA(mpath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); if (handle == INVALID_HANDLE_VALUE) { @@ -299,11 +302,11 @@ std::string RemovableDriveManager::get_last_drive_path() { if (!m_current_drives.empty()) { -#if _WIN32 - return m_current_drives.back().path + "\\"; -#else +//#if _WIN32 +// return m_current_drives.back().path + "\\"; +//#else return m_current_drives.back().path; -#endif +//#endif } return ""; } From 5ea512f1f29bda999fe497c56e088e53a681cdba Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 4 Dec 2019 10:05:18 +0100 Subject: [PATCH 062/123] osx search for drives --- src/slic3r/GUI/RemovableDriveManager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 9b3020e79ef..bdc1727403e 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -148,6 +148,9 @@ void RemovableDriveManager::search_for_drives() //search /media/* folder search_path("/media/*", "/media"); + //search /Volumes/* folder (OSX) + search_path("/Volumes/*", "/Volumes"); + std::string path(std::getenv("USER")); std::string pp(path); //std::cout << "user: "<< path << "\n"; From 1084534d5a238bb37b6a4686c07570219c92f245 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 4 Dec 2019 11:47:47 +0100 Subject: [PATCH 063/123] linux owner checking --- src/slic3r/GUI/RemovableDriveManager.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index bdc1727403e..99520b84297 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -154,7 +154,10 @@ void RemovableDriveManager::search_for_drives() std::string path(std::getenv("USER")); std::string pp(path); //std::cout << "user: "<< path << "\n"; - if(path == "root"){ //if program is run with sudo, we have to search for all users + //if program is run with sudo, we have to search for all users + // but do we want that? + /* + if(path == "root"){ while (true) { passwd* entry = getpwent(); if (!entry) { @@ -174,6 +177,7 @@ void RemovableDriveManager::search_for_drives() } endpwent(); }else + */ { //search /media/USERNAME/* folder pp = "/media/"+pp; @@ -187,7 +191,7 @@ void RemovableDriveManager::search_for_drives() } - //std::cout << "found drives:" <pw_name == username) + { + std::string name = basename(globbuf.gl_pathv[i]); + m_current_drives.push_back(DriveData(name,globbuf.gl_pathv[i])); + } + } } } }else From 95ebfd62ee27cbac81ae8f6ff64708d23b7f5df4 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 4 Dec 2019 13:10:08 +0100 Subject: [PATCH 064/123] path check --- src/slic3r/GUI/RemovableDriveManager.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 99520b84297..e1ab1626c5c 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -248,6 +248,15 @@ void RemovableDriveManager::eject_drive(const std::string &path) { if((*it).path == path) { + + std::string correct_path(path); + for (size_t i = 0; i < correct_path.size(); ++i) + { + if(correct_path[i]==' ') + { + correct_path = correct_path.insert(i,"\\"); + } + } std::cout<<"Ejecting "<<(*it).name<<" from "<< (*it).path<<"\n"; std::string command = "umount "; command += (*it).path; @@ -301,6 +310,7 @@ bool RemovableDriveManager::update(long time) } search_for_drives(); check_and_notify(); + eject_drive(m_current_drives.back().path); return !m_current_drives.empty(); } From 162016644461493cad132fe9b11817d32415b2ed Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 4 Dec 2019 13:13:18 +0100 Subject: [PATCH 065/123] path check --- src/slic3r/GUI/RemovableDriveManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index e1ab1626c5c..3ff5735f911 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -255,6 +255,7 @@ void RemovableDriveManager::eject_drive(const std::string &path) if(correct_path[i]==' ') { correct_path = correct_path.insert(i,"\\"); + i++; } } std::cout<<"Ejecting "<<(*it).name<<" from "<< (*it).path<<"\n"; From e3c3c568ec75192a924e406953d32cc7cb6fe842 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 4 Dec 2019 13:18:08 +0100 Subject: [PATCH 066/123] path check --- src/slic3r/GUI/RemovableDriveManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 3ff5735f911..7216763eec1 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -254,13 +254,13 @@ void RemovableDriveManager::eject_drive(const std::string &path) { if(correct_path[i]==' ') { - correct_path = correct_path.insert(i,"\\"); + correct_path = correct_path.insert(i,1,'\\'); i++; } } - std::cout<<"Ejecting "<<(*it).name<<" from "<< (*it).path<<"\n"; + std::cout<<"Ejecting "<<(*it).name<<" from "<< correct_path<"\n"; std::string command = "umount "; - command += (*it).path; + command += correct_path; int err = system(command.c_str()); if(err) { From 1a0f09616b55f3561852ab1b643bd81836f9aecc Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 4 Dec 2019 13:21:41 +0100 Subject: [PATCH 067/123] path check --- src/slic3r/GUI/RemovableDriveManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 7216763eec1..c859a5d8723 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -258,7 +258,7 @@ void RemovableDriveManager::eject_drive(const std::string &path) i++; } } - std::cout<<"Ejecting "<<(*it).name<<" from "<< correct_path<"\n"; + std::cout<<"Ejecting "<<(*it).name<<" from "<< correct_path<<"\n"; std::string command = "umount "; command += correct_path; int err = system(command.c_str()); From 3ed7a6ceb44b1cd6d61f0dcd106314bd246569c2 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 4 Dec 2019 13:30:25 +0100 Subject: [PATCH 068/123] path check --- src/slic3r/GUI/RemovableDriveManager.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index c859a5d8723..3d77606c815 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -259,7 +259,13 @@ void RemovableDriveManager::eject_drive(const std::string &path) } } std::cout<<"Ejecting "<<(*it).name<<" from "<< correct_path<<"\n"; - std::string command = "umount "; + + std::string command = ""; +#if __APPLE__ + command = "diskutil unmount "; +#else + command = "umount "; +#endif command += correct_path; int err = system(command.c_str()); if(err) From 0198fea9c3ef4a4fc8e6f0c37488cb074069d8e7 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 4 Dec 2019 13:43:28 +0100 Subject: [PATCH 069/123] comment testing lines --- src/slic3r/GUI/RemovableDriveManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 3d77606c815..0665e57dc2a 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -317,7 +317,7 @@ bool RemovableDriveManager::update(long time) } search_for_drives(); check_and_notify(); - eject_drive(m_current_drives.back().path); + //eject_drive(m_current_drives.back().path); return !m_current_drives.empty(); } From 7d569c1c91ffc8f147704cf8dc3e5afb6036038c Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 4 Dec 2019 15:27:33 +0100 Subject: [PATCH 070/123] refactoring --- src/slic3r/GUI/RemovableDriveManager.cpp | 14 +++++++------- src/slic3r/GUI/RemovableDriveManager.hpp | 3 ++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 0665e57dc2a..a655425fc4a 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -121,6 +121,7 @@ bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path) } void RemovableDriveManager::register_window() { + //std::cout << "Registering for device notification\n"; /* WNDCLASSEX wndClass; @@ -137,6 +138,7 @@ void RemovableDriveManager::register_window() wndClass.lpszMenuName = NULL; wndClass.hIconSm = wndClass.hIcon; */ + //std::cout << "Failed\n"; } #else void RemovableDriveManager::search_for_drives() @@ -191,7 +193,7 @@ void RemovableDriveManager::search_for_drives() } - std::cout << "found drives:" < callback); void print(); private: - RemovableDriveManager():m_drives_count(0){} + RemovableDriveManager():m_drives_count(0),m_last_update(0){} void search_for_drives(); void check_and_notify(); std::vector m_current_drives; std::vector> m_callbacks; size_t m_drives_count; + long m_last_update; #if _WIN32 void register_window(); #else From f00a0f98c712c467d7008b7456b0ddb1771b0911 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 5 Dec 2019 14:07:02 +0100 Subject: [PATCH 071/123] last path functions --- src/slic3r/GUI/GUI_App.cpp | 3 +- src/slic3r/GUI/Plater.cpp | 2 + src/slic3r/GUI/RemovableDriveManager.cpp | 174 +++++++++++++++++++++-- src/slic3r/GUI/RemovableDriveManager.hpp | 12 +- 4 files changed, 173 insertions(+), 18 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index e6c92cd0a8d..0d608876eb4 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -272,7 +272,8 @@ bool GUI_App::on_init_inner() this->obj_manipul()->update_if_dirty(); - RemovableDriveManager::get_instance().update(wxGetLocalTime()); + //RemovableDriveManager::get_instance().update(wxGetLocalTime()); + std::cout << RemovableDriveManager::get_instance().is_last_drive_removed() << "\n"; // Preset updating & Configwizard are done after the above initializations, // and after MainFrame is created & shown. diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 3e3827926fc..b8b2f45e8b0 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4681,9 +4681,11 @@ void Plater::export_gcode() fs::path path = into_path(dlg.GetPath()); wxGetApp().app_config->update_last_output_dir(path.parent_path().string()); output_path = std::move(path); + RemovableDriveManager::get_instance().set_last_save_path(output_path.string()); } if (! output_path.empty()) p->export_gcode(std::move(output_path), PrintHostJob()); + } void Plater::export_stl(bool extended, bool selection_only) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index a655425fc4a..146bebc1195 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -7,8 +7,11 @@ #include #include #include -DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, - 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED); + +//#include +//GUID WceusbshGUID = { 0x25dbce51, 0x6c8f, 0x4a72, +// 0x8a,0x6d,0xb5,0x4c,0x2b,0x4f,0xc8,0x35 }; + #else //linux includes #include @@ -26,6 +29,7 @@ namespace GUI { #if _WIN32 +//INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); void RemovableDriveManager::search_for_drives() { m_current_drives.clear(); @@ -84,7 +88,7 @@ void RemovableDriveManager::eject_drive(const std::string &path) { std::string mpath = "\\\\.\\" + path; mpath = mpath.substr(0, mpath.size() - 1); - std::cout << "Ejecting " << mpath << "\n"; + //std::cout << "Ejecting " << mpath << "\n"; HANDLE handle = CreateFileA(mpath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); if (handle == INVALID_HANDLE_VALUE) { @@ -119,10 +123,24 @@ bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path) } return false; } +std::string RemovableDriveManager::get_drive_from_path(const std::string& path) +{ + int letter = PathGetDriveNumberA(path.c_str()); + for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) + { + char drive = (*it).path[0]; + if (drive == ('A' + letter)) + return (*it).path; + } + return ""; +} void RemovableDriveManager::register_window() { - //std::cout << "Registering for device notification\n"; /* + std::cout << "Registering for device notification\n"; + + + WNDCLASSEX wndClass; wndClass.cbSize = sizeof(WNDCLASSEX); @@ -134,12 +152,109 @@ void RemovableDriveManager::register_window() wndClass.hIcon = LoadIcon(0, IDI_APPLICATION); wndClass.hbrBackground = CreateSolidBrush(RGB(192, 192, 192)); wndClass.hCursor = LoadCursor(0, IDC_ARROW); - wndClass.lpszClassName = L"SlicerWindowClass"; + wndClass.lpszClassName = L"PrusaSlicer_aux_class"; wndClass.lpszMenuName = NULL; wndClass.hIconSm = wndClass.hIcon; - */ - //std::cout << "Failed\n"; + + HINSTANCE hInstanceExe = GetModuleHandle(NULL); + + HWND hWnd = CreateWindowEx( + WS_EX_CLIENTEDGE | WS_EX_APPWINDOW, + L"PrusaSlicer_aux_class", + L"PrusaSlicer_aux_wnd", + WS_OVERLAPPEDWINDOW, // style + CW_USEDEFAULT, 0, + 640, 480, + NULL, NULL, + hInstanceExe, + NULL); +*/ } +/* +INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + LRESULT lRet = 1; + static HDEVNOTIFY hDeviceNotify; + static HWND hEditWnd; + static ULONGLONG msgCount = 0; + + switch (message) + { + case WM_CREATE: + + + DEV_BROADCAST_DEVICEINTERFACE NotificationFilter; + + ZeroMemory(&NotificationFilter, sizeof(NotificationFilter)); + NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); + NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; + NotificationFilter.dbcc_classguid = WceusbshGUID; + + hDeviceNotify = RegisterDeviceNotification( + hWnd, // events recipient + &NotificationFilter, // type of device + DEVICE_NOTIFY_WINDOW_HANDLE // type of recipient handle + ); + break; + + + + case WM_DEVICECHANGE: + { + std::cout << "WM_DEVICECHANGE\n"; + /* + // This is the actual message from the interface via Windows messaging. + // This code includes some additional decoding for this particular device type + // and some common validation checks. + // + // Note that not all devices utilize these optional parameters in the same + // way. Refer to the extended information for your particular device type + // specified by your GUID. + // + PDEV_BROADCAST_DEVICEINTERFACE b = (PDEV_BROADCAST_DEVICEINTERFACE)lParam; + TCHAR strBuff[256]; + + // Output some messages to the window. + switch (wParam) + { + case DBT_DEVICEARRIVAL: + msgCount++; + StringCchPrintf( + strBuff, 256, + TEXT("Message %d: DBT_DEVICEARRIVAL\n"), msgCount); + break; + case DBT_DEVICEREMOVECOMPLETE: + msgCount++; + StringCchPrintf( + strBuff, 256, + TEXT("Message %d: DBT_DEVICEREMOVECOMPLETE\n"), msgCount); + break; + case DBT_DEVNODES_CHANGED: + msgCount++; + StringCchPrintf( + strBuff, 256, + TEXT("Message %d: DBT_DEVNODES_CHANGED\n"), msgCount); + break; + default: + msgCount++; + StringCchPrintf( + strBuff, 256, + TEXT("Message %d: WM_DEVICECHANGE message received, value %d unhandled.\n"), + msgCount, wParam); + break; + } + OutputMessage(hEditWnd, wParam, (LPARAM)strBuff); + / + } + break; + default: + // Send all other messages on to the default windows handler. + lRet = DefWindowProc(hWnd, message, wParam, lParam); + break; + } + return lRet; +} +*/ #else void RemovableDriveManager::search_for_drives() { @@ -294,6 +409,16 @@ bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path) } return false; } +std::string RemovableDriveManager::get_drive_from_path(const std::string& path) +{ + //check if same filesystem + for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) + { + if (compare_filesystem_id(path, (*it).path)) + return (*it).path; + } + return ""; +} #endif bool RemovableDriveManager::update(long time) { @@ -301,7 +426,7 @@ bool RemovableDriveManager::update(long time) { //add_callback([](void) { RemovableDriveManager::get_instance().print(); }); #if _WIN32 - register_window(); + //register_window(); #endif } if(time != 0) //time = 0 is forced update @@ -338,11 +463,9 @@ std::string RemovableDriveManager::get_last_drive_path() { if (!m_current_drives.empty()) { -//#if _WIN32 -// return m_current_drives.back().path + "\\"; -//#else + if (m_last_save_path != "") + return m_last_save_path; return m_current_drives.back().path; -//#endif } return ""; } @@ -356,9 +479,12 @@ void RemovableDriveManager::check_and_notify() if(m_drives_count != m_current_drives.size()) { //std::cout<<" vs "<< m_current_drives.size(); - for (auto it = m_callbacks.begin(); it != m_callbacks.end(); ++it) + if(m_drives_count > m_current_drives.size()) { - (*it)(); + for (auto it = m_callbacks.begin(); it != m_callbacks.end(); ++it) + { + (*it)(); + } } m_drives_count = m_current_drives.size(); } @@ -368,6 +494,26 @@ void RemovableDriveManager::add_callback(std::function callback) { m_callbacks.push_back(callback); } +void RemovableDriveManager::set_last_save_path(const std::string& path) +{ + std::string last_drive = get_drive_from_path(path); + if(last_drive != "") + { + m_last_save_path = last_drive; + } +} +bool RemovableDriveManager::is_last_drive_removed() +{ + if(m_last_save_path == "") + { + return true; + } + return !is_drive_mounted(m_last_save_path); +} +void RemovableDriveManager::reset_last_save_path() +{ + m_last_save_path = ""; +} void RemovableDriveManager::print() { std::cout << "notified\n"; diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index c65a7fe6252..be5ae5968e5 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -24,24 +24,30 @@ public: void operator=(RemovableDriveManager const&) = delete; //update() searches for removable devices, returns false if empty. - bool update(long time = 0); //time = 0 is forced update + bool update(long time = 0); //time = 0 is forced update, time expects wxGetLocalTime() bool is_drive_mounted(const std::string &path); void eject_drive(const std::string &path); std::string get_last_drive_path(); std::vector get_all_drives(); bool is_path_on_removable_drive(const std::string &path); - void add_callback(std::function callback); + void add_callback(std::function callback); // callback will notify every drive removal. to see if it was last used drive call is_last_drive_removed() + void set_last_save_path(const std::string &path); + bool is_last_drive_removed(); //if we dont need info about this drive, call reset_last_save_path(); + void reset_last_save_path(); void print(); private: - RemovableDriveManager():m_drives_count(0),m_last_update(0){} + RemovableDriveManager():m_drives_count(0),m_last_update(0),m_last_save_path(""){} void search_for_drives(); void check_and_notify(); + std::string get_drive_from_path(const std::string& path);//returns drive path (same as path in DriveData) if exists otherwise empty string "" std::vector m_current_drives; std::vector> m_callbacks; size_t m_drives_count; long m_last_update; + std::string m_last_save_path; #if _WIN32 void register_window(); + //INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); #else void search_path(const std::string &path, const std::string &parent_path); bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); From e10ae44932d09fda1ae2e037fb2aed6d024d901e Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 5 Dec 2019 16:22:54 +0100 Subject: [PATCH 072/123] last save path --- src/slic3r/GUI/GUI_App.cpp | 7 ++++--- src/slic3r/GUI/RemovableDriveManager.cpp | 10 ++++++++-- src/slic3r/GUI/RemovableDriveManager.hpp | 3 ++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 0d608876eb4..28812dcf433 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -272,9 +272,10 @@ bool GUI_App::on_init_inner() this->obj_manipul()->update_if_dirty(); - //RemovableDriveManager::get_instance().update(wxGetLocalTime()); - std::cout << RemovableDriveManager::get_instance().is_last_drive_removed() << "\n"; - + + RemovableDriveManager::get_instance().update(wxGetLocalTime()); + + // Preset updating & Configwizard are done after the above initializations, // and after MainFrame is created & shown. // The extra CallAfter() is needed because of Mac, where this is the only way diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 146bebc1195..e94ea6918ad 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -420,11 +420,11 @@ std::string RemovableDriveManager::get_drive_from_path(const std::string& path) return ""; } #endif -bool RemovableDriveManager::update(long time) +bool RemovableDriveManager::update(const long time) { if(m_last_update == 0) { - //add_callback([](void) { RemovableDriveManager::get_instance().print(); }); + add_callback([](void) { RemovableDriveManager::get_instance().print(); }); #if _WIN32 //register_window(); #endif @@ -510,12 +510,18 @@ bool RemovableDriveManager::is_last_drive_removed() } return !is_drive_mounted(m_last_save_path); } +bool RemovableDriveManager::is_last_drive_removed_with_update(const long time) +{ + update(time); + return is_last_drive_removed(); +} void RemovableDriveManager::reset_last_save_path() { m_last_save_path = ""; } void RemovableDriveManager::print() { + //std::cout << "Removed Device: "<<(int)is_last_drive_removed()<<"\n"; std::cout << "notified\n"; } }}//namespace Slicer::Gui:: \ No newline at end of file diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index be5ae5968e5..906667244be 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -24,7 +24,7 @@ public: void operator=(RemovableDriveManager const&) = delete; //update() searches for removable devices, returns false if empty. - bool update(long time = 0); //time = 0 is forced update, time expects wxGetLocalTime() + bool update(const long time = 0); //time = 0 is forced update, time expects wxGetLocalTime() bool is_drive_mounted(const std::string &path); void eject_drive(const std::string &path); std::string get_last_drive_path(); @@ -33,6 +33,7 @@ public: void add_callback(std::function callback); // callback will notify every drive removal. to see if it was last used drive call is_last_drive_removed() void set_last_save_path(const std::string &path); bool is_last_drive_removed(); //if we dont need info about this drive, call reset_last_save_path(); + bool is_last_drive_removed_with_update(const long time = 0); // param as update() void reset_last_save_path(); void print(); private: From 536c7e0f3b01f088ea6fa261e93e94bfe48a2c34 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Fri, 6 Dec 2019 13:17:36 +0100 Subject: [PATCH 073/123] callback only for used device --- src/slic3r/GUI/RemovableDriveManager.cpp | 2 +- src/slic3r/GUI/RemovableDriveManager.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index e94ea6918ad..6581d536141 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -479,7 +479,7 @@ void RemovableDriveManager::check_and_notify() if(m_drives_count != m_current_drives.size()) { //std::cout<<" vs "<< m_current_drives.size(); - if(m_drives_count > m_current_drives.size()) + if(m_drives_count > m_current_drives.size() && m_last_save_path != "" && !is_drive_mounted(m_last_save_path)) { for (auto it = m_callbacks.begin(); it != m_callbacks.end(); ++it) { diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 906667244be..741b4424ab1 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -30,7 +30,7 @@ public: std::string get_last_drive_path(); std::vector get_all_drives(); bool is_path_on_removable_drive(const std::string &path); - void add_callback(std::function callback); // callback will notify every drive removal. to see if it was last used drive call is_last_drive_removed() + void add_callback(std::function callback); // callback will notify only if device with last save path was removed void set_last_save_path(const std::string &path); bool is_last_drive_removed(); //if we dont need info about this drive, call reset_last_save_path(); bool is_last_drive_removed_with_update(const long time = 0); // param as update() From d47d976112d3785fd553457d3b01d59953031645 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Fri, 6 Dec 2019 13:21:44 +0100 Subject: [PATCH 074/123] erase callbacks --- src/slic3r/GUI/RemovableDriveManager.cpp | 4 ++++ src/slic3r/GUI/RemovableDriveManager.hpp | 1 + 2 files changed, 5 insertions(+) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 6581d536141..1fbc33fc579 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -494,6 +494,10 @@ void RemovableDriveManager::add_callback(std::function callback) { m_callbacks.push_back(callback); } +void RemovableDriveManager::erase_callbacks() +{ + m_callbacks.clear(); +} void RemovableDriveManager::set_last_save_path(const std::string& path) { std::string last_drive = get_drive_from_path(path); diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 741b4424ab1..8d9e65c47ec 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -31,6 +31,7 @@ public: std::vector get_all_drives(); bool is_path_on_removable_drive(const std::string &path); void add_callback(std::function callback); // callback will notify only if device with last save path was removed + void erase_callbacks(); // erases all callbacks added by add_callback() void set_last_save_path(const std::string &path); bool is_last_drive_removed(); //if we dont need info about this drive, call reset_last_save_path(); bool is_last_drive_removed_with_update(const long time = 0); // param as update() From 5b29d727a934c48f8b7fc955752c7e2cd083ac40 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Fri, 6 Dec 2019 16:51:04 +0100 Subject: [PATCH 075/123] windows registration for device notif(thru hidden app) - windows doesnt need update now --- src/slic3r/GUI/GUI_App.cpp | 3 +- src/slic3r/GUI/RemovableDriveManager.cpp | 108 ++++++++--------------- src/slic3r/GUI/RemovableDriveManager.hpp | 2 + 3 files changed, 40 insertions(+), 73 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 28812dcf433..72c84ba799f 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -273,7 +273,7 @@ bool GUI_App::on_init_inner() this->obj_manipul()->update_if_dirty(); - RemovableDriveManager::get_instance().update(wxGetLocalTime()); + //RemovableDriveManager::get_instance().update(wxGetLocalTime()); // Preset updating & Configwizard are done after the above initializations, @@ -303,6 +303,7 @@ bool GUI_App::on_init_inner() preset_updater->slic3r_update_notify(); preset_updater->sync(preset_bundle); }); + RemovableDriveManager::get_instance().init(); } }); diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 1fbc33fc579..5daa9eb261e 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -8,9 +8,9 @@ #include #include -//#include -//GUID WceusbshGUID = { 0x25dbce51, 0x6c8f, 0x4a72, -// 0x8a,0x6d,0xb5,0x4c,0x2b,0x4f,0xc8,0x35 }; +#include +GUID WceusbshGUID = { 0x25dbce51, 0x6c8f, 0x4a72, + 0x8a,0x6d,0xb5,0x4c,0x2b,0x4f,0xc8,0x35 }; #else //linux includes @@ -29,7 +29,7 @@ namespace GUI { #if _WIN32 -//INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); +INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); void RemovableDriveManager::search_for_drives() { m_current_drives.clear(); @@ -136,13 +136,8 @@ std::string RemovableDriveManager::get_drive_from_path(const std::string& path) } void RemovableDriveManager::register_window() { - /* std::cout << "Registering for device notification\n"; - - - WNDCLASSEX wndClass; - wndClass.cbSize = sizeof(WNDCLASSEX); wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wndClass.hInstance = reinterpret_cast(GetModuleHandle(0)); @@ -155,34 +150,41 @@ void RemovableDriveManager::register_window() wndClass.lpszClassName = L"PrusaSlicer_aux_class"; wndClass.lpszMenuName = NULL; wndClass.hIconSm = wndClass.hIcon; - - HINSTANCE hInstanceExe = GetModuleHandle(NULL); + if(!RegisterClassEx(&wndClass)) + { + DWORD err = GetLastError(); + return; + } HWND hWnd = CreateWindowEx( - WS_EX_CLIENTEDGE | WS_EX_APPWINDOW, + WS_EX_NOACTIVATE, L"PrusaSlicer_aux_class", L"PrusaSlicer_aux_wnd", - WS_OVERLAPPEDWINDOW, // style + WS_DISABLED, // style CW_USEDEFAULT, 0, 640, 480, NULL, NULL, - hInstanceExe, + GetModuleHandle(NULL), NULL); -*/ + if(hWnd == NULL) + { + DWORD err = GetLastError(); + } + //ShowWindow(hWnd, SW_SHOWNORMAL); + UpdateWindow(hWnd); } -/* + INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { LRESULT lRet = 1; static HDEVNOTIFY hDeviceNotify; + static HWND hEditWnd; static ULONGLONG msgCount = 0; switch (message) { case WM_CREATE: - - DEV_BROADCAST_DEVICEINTERFACE NotificationFilter; ZeroMemory(&NotificationFilter, sizeof(NotificationFilter)); @@ -196,55 +198,13 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP DEVICE_NOTIFY_WINDOW_HANDLE // type of recipient handle ); break; - - - case WM_DEVICECHANGE: { - std::cout << "WM_DEVICECHANGE\n"; - /* - // This is the actual message from the interface via Windows messaging. - // This code includes some additional decoding for this particular device type - // and some common validation checks. - // - // Note that not all devices utilize these optional parameters in the same - // way. Refer to the extended information for your particular device type - // specified by your GUID. - // - PDEV_BROADCAST_DEVICEINTERFACE b = (PDEV_BROADCAST_DEVICEINTERFACE)lParam; - TCHAR strBuff[256]; - - // Output some messages to the window. - switch (wParam) + if(wParam == DBT_DEVICEREMOVECOMPLETE) { - case DBT_DEVICEARRIVAL: - msgCount++; - StringCchPrintf( - strBuff, 256, - TEXT("Message %d: DBT_DEVICEARRIVAL\n"), msgCount); - break; - case DBT_DEVICEREMOVECOMPLETE: - msgCount++; - StringCchPrintf( - strBuff, 256, - TEXT("Message %d: DBT_DEVICEREMOVECOMPLETE\n"), msgCount); - break; - case DBT_DEVNODES_CHANGED: - msgCount++; - StringCchPrintf( - strBuff, 256, - TEXT("Message %d: DBT_DEVNODES_CHANGED\n"), msgCount); - break; - default: - msgCount++; - StringCchPrintf( - strBuff, 256, - TEXT("Message %d: WM_DEVICECHANGE message received, value %d unhandled.\n"), - msgCount, wParam); - break; + std::cout << "WM_DEVICECHANGE\n"; + RemovableDriveManager::get_instance().on_drive_removed_callback(); } - OutputMessage(hEditWnd, wParam, (LPARAM)strBuff); - / } break; default: @@ -254,7 +214,7 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP } return lRet; } -*/ + #else void RemovableDriveManager::search_for_drives() { @@ -420,15 +380,16 @@ std::string RemovableDriveManager::get_drive_from_path(const std::string& path) return ""; } #endif +void RemovableDriveManager::init() +{ + add_callback([](void) { RemovableDriveManager::get_instance().print(); }); +#if _WIN32 + register_window(); +#endif + update(); +} bool RemovableDriveManager::update(const long time) { - if(m_last_update == 0) - { - add_callback([](void) { RemovableDriveManager::get_instance().print(); }); -#if _WIN32 - //register_window(); -#endif - } if(time != 0) //time = 0 is forced update { long diff = m_last_update - time; @@ -442,7 +403,6 @@ bool RemovableDriveManager::update(const long time) } search_for_drives(); check_and_notify(); - //eject_drive(m_current_drives.back().path); return !m_current_drives.empty(); } @@ -523,6 +483,10 @@ void RemovableDriveManager::reset_last_save_path() { m_last_save_path = ""; } +void RemovableDriveManager::on_drive_removed_callback() +{ + update(); +} void RemovableDriveManager::print() { //std::cout << "Removed Device: "<<(int)is_last_drive_removed()<<"\n"; diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 8d9e65c47ec..210d89477b2 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -24,6 +24,7 @@ public: void operator=(RemovableDriveManager const&) = delete; //update() searches for removable devices, returns false if empty. + void init(); bool update(const long time = 0); //time = 0 is forced update, time expects wxGetLocalTime() bool is_drive_mounted(const std::string &path); void eject_drive(const std::string &path); @@ -36,6 +37,7 @@ public: bool is_last_drive_removed(); //if we dont need info about this drive, call reset_last_save_path(); bool is_last_drive_removed_with_update(const long time = 0); // param as update() void reset_last_save_path(); + void on_drive_removed_callback(); void print(); private: RemovableDriveManager():m_drives_count(0),m_last_update(0),m_last_save_path(""){} From fd07cbccfbf3966e9c6cb728a52b2547a6ba86a7 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 9 Dec 2019 15:33:10 +0100 Subject: [PATCH 076/123] osx device unmount callback - not sure if will build --- src/slic3r/CMakeLists.txt | 1 + src/slic3r/GUI/RemovableDriveManager.cpp | 11 ++--- src/slic3r/GUI/RemovableDriveManager.hpp | 4 +- src/slic3r/GUI/RemovableDriveManager.mm | 51 ++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 src/slic3r/GUI/RemovableDriveManager.mm diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 2d7b99b73d4..246f1365b08 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -169,6 +169,7 @@ if (APPLE) list(APPEND SLIC3R_GUI_SOURCES Utils/RetinaHelperImpl.mm Utils/MacDarkMode.mm + GUI/RemovableDriveManager.mm ) endif () diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 5daa9eb261e..166728e68ba 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -203,7 +203,7 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP if(wParam == DBT_DEVICEREMOVECOMPLETE) { std::cout << "WM_DEVICECHANGE\n"; - RemovableDriveManager::get_instance().on_drive_removed_callback(); + RemovableDriveManager::get_instance().update(); } } break; @@ -219,6 +219,10 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP void RemovableDriveManager::search_for_drives() { +#if __APPLE__ + list_devices(); +#endif + m_current_drives.clear(); m_current_drives.reserve(26); @@ -483,10 +487,7 @@ void RemovableDriveManager::reset_last_save_path() { m_last_save_path = ""; } -void RemovableDriveManager::on_drive_removed_callback() -{ - update(); -} + void RemovableDriveManager::print() { //std::cout << "Removed Device: "<<(int)is_last_drive_removed()<<"\n"; diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 210d89477b2..501c16b71ad 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -37,7 +37,6 @@ public: bool is_last_drive_removed(); //if we dont need info about this drive, call reset_last_save_path(); bool is_last_drive_removed_with_update(const long time = 0); // param as update() void reset_last_save_path(); - void on_drive_removed_callback(); void print(); private: RemovableDriveManager():m_drives_count(0),m_last_update(0),m_last_save_path(""){} @@ -52,6 +51,9 @@ private: #if _WIN32 void register_window(); //INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); +#elif __APPLE__ + void register_window(); + void list_devices(); #else void search_path(const std::string &path, const std::string &parent_path); bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); diff --git a/src/slic3r/GUI/RemovableDriveManager.mm b/src/slic3r/GUI/RemovableDriveManager.mm new file mode 100644 index 00000000000..a1358625fc0 --- /dev/null +++ b/src/slic3r/GUI/RemovableDriveManager.mm @@ -0,0 +1,51 @@ +#import "RemovableDriveManager.hpp" + +@implementation RemovableDriveManager + +namespace Slic3r { +namespace GUI { + +void RemovableDriveManager::register_window() +{ + //[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(volumesChanged:) name:NSWorkspaceDidMountNotification object: nil]; + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(on_device_unmount:) name:NSWorkspaceDidUnmountNotification object:nil]; +} + +-(void) on_device_unmount: (NSNotification*) notification +{ + NSLog(@"on device change"); + RemovableDriveManager::get_instance().update(); +} + +-(void) RemovableDriveManager::list_devices() +{ + NSLog(@"---"); + NSArray* devices = [[NSWorkspace sharedWorkspace] mountedRemovableMedia]; + for (NSString* volumePath in listOfMedia) + { + NSLog(@"@", volumePath); + } + NSLog(@"--"); + //removable here means CD not USB :/ + NSArray* listOfMedia = [[NSWorkspace sharedWorkspace] mountedLocalVolumePaths]; + NSLog(@"%@", listOfMedia); + + for (NSString* volumePath in listOfMedia) + { + BOOL isRemovable = NO; + BOOL isWritable = NO; + BOOL isUnmountable = NO; + NSString* description = [NSString string]; + NSString* type = [NSString string]; + + BOOL result = [[NSWorkspace sharedWorkspace] getFileSystemInfoForPath:volumePath + isRemovable:&isRemovable + isWritable:&isWritable + isUnmountable:&isUnmountable + description:&description + type:&type]; + NSLog(@"Result:%i Volume: %@, Removable:%i, W:%i, Unmountable:%i, Desc:%@, type:%@", result, volumePath, isRemovable, isWritable, isUnmountable, description, type); + } +} + +}}//namespace Slicer::GUI \ No newline at end of file From 81b8646a6d6a530f29e69ec823be68f152e8c118 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 9 Dec 2019 17:12:22 +0100 Subject: [PATCH 077/123] init call --- src/slic3r/GUI/GUI_App.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 72c84ba799f..e13701f61da 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -262,6 +262,8 @@ bool GUI_App::on_init_inner() m_printhost_job_queue.reset(new PrintHostJobQueue(mainframe->printhost_queue_dlg())); + RemovableDriveManager::get_instance().init(); + Bind(wxEVT_IDLE, [this](wxIdleEvent& event) { if (! plater_) @@ -303,7 +305,7 @@ bool GUI_App::on_init_inner() preset_updater->slic3r_update_notify(); preset_updater->sync(preset_bundle); }); - RemovableDriveManager::get_instance().init(); + } }); From d34609f52890f2c3ebda64d8125c5cee3ff698dc Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 10 Dec 2019 10:08:57 +0100 Subject: [PATCH 078/123] macos mm files --- src/slic3r/CMakeLists.txt | 3 +- src/slic3r/GUI/RemovableDriveManager.hpp | 3 +- src/slic3r/GUI/RemovableDriveManagerMM.h | 9 ++++++ ...eManager.mm => RemovableDriveManagerMM.mm} | 29 +++++++++++++++---- 4 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 src/slic3r/GUI/RemovableDriveManagerMM.h rename src/slic3r/GUI/{RemovableDriveManager.mm => RemovableDriveManagerMM.mm} (86%) diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 246f1365b08..a06a8cf1d14 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -169,7 +169,8 @@ if (APPLE) list(APPEND SLIC3R_GUI_SOURCES Utils/RetinaHelperImpl.mm Utils/MacDarkMode.mm - GUI/RemovableDriveManager.mm + GUI/RemovableDriveManagerMM.mm + GUI/RemovableDriveManagerMM.h ) endif () diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 501c16b71ad..04bbe48b5d0 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -52,8 +52,9 @@ private: void register_window(); //INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); #elif __APPLE__ + void *m_rdmmm; void register_window(); - void list_devices(); + //void list_devices(); #else void search_path(const std::string &path, const std::string &parent_path); bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.h b/src/slic3r/GUI/RemovableDriveManagerMM.h new file mode 100644 index 00000000000..8f783c2d2a9 --- /dev/null +++ b/src/slic3r/GUI/RemovableDriveManagerMM.h @@ -0,0 +1,9 @@ +#import + +@interface RemovableDriveManagerMM : NSObject + +-(instancetype) init; +-(void) add_unmount_observer; +-(void) on_device_unmount: (NSNotification*) notification; + +@end \ No newline at end of file diff --git a/src/slic3r/GUI/RemovableDriveManager.mm b/src/slic3r/GUI/RemovableDriveManagerMM.mm similarity index 86% rename from src/slic3r/GUI/RemovableDriveManager.mm rename to src/slic3r/GUI/RemovableDriveManagerMM.mm index a1358625fc0..e4e324654ec 100644 --- a/src/slic3r/GUI/RemovableDriveManager.mm +++ b/src/slic3r/GUI/RemovableDriveManagerMM.mm @@ -1,22 +1,39 @@ #import "RemovableDriveManager.hpp" -@implementation RemovableDriveManager +#import + +@implementation RemovableDriveManagerMM namespace Slic3r { namespace GUI { -void RemovableDriveManager::register_window() +-(instancetype) init { - //[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(volumesChanged:) name:NSWorkspaceDidMountNotification object: nil]; - [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(on_device_unmount:) name:NSWorkspaceDidUnmountNotification object:nil]; + self = [super init]; + if(self) + { + [self add_unmount_observer] + } + return self; } - -(void) on_device_unmount: (NSNotification*) notification { NSLog(@"on device change"); RemovableDriveManager::get_instance().update(); } +-(void) add_unmount_observer +{ + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(on_device_unmount:) name:NSWorkspaceDidUnmountNotification object:nil]; +} +void RemovableDriveManager::register_window() +{ + m_rdmmm = nullptr; + m_rdmmm = [[RemovableDriveManagerMM alloc] init]; +} + + +/* -(void) RemovableDriveManager::list_devices() { NSLog(@"---"); @@ -47,5 +64,5 @@ void RemovableDriveManager::register_window() NSLog(@"Result:%i Volume: %@, Removable:%i, W:%i, Unmountable:%i, Desc:%@, type:%@", result, volumePath, isRemovable, isWritable, isUnmountable, description, type); } } - +*/ }}//namespace Slicer::GUI \ No newline at end of file From 56bb3ade342e257d581b37a2c43ec34a55a03615 Mon Sep 17 00:00:00 2001 From: Slic3rPE Date: Tue, 10 Dec 2019 11:17:12 +0100 Subject: [PATCH 079/123] macos implementation --- src/slic3r/GUI/RemovableDriveManager.cpp | 8 +++++--- src/slic3r/GUI/RemovableDriveManager.hpp | 4 +++- src/slic3r/GUI/RemovableDriveManagerMM.mm | 18 ++++++++++-------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 166728e68ba..8145c90760b 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -218,11 +218,11 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP #else void RemovableDriveManager::search_for_drives() { - + /* #if __APPLE__ list_devices(); #endif - +*/ m_current_drives.clear(); m_current_drives.reserve(26); @@ -389,6 +389,8 @@ void RemovableDriveManager::init() add_callback([](void) { RemovableDriveManager::get_instance().print(); }); #if _WIN32 register_window(); +#elif __APPLE__ + register_window(); #endif update(); } @@ -493,4 +495,4 @@ void RemovableDriveManager::print() //std::cout << "Removed Device: "<<(int)is_last_drive_removed()<<"\n"; std::cout << "notified\n"; } -}}//namespace Slicer::Gui:: \ No newline at end of file +}}//namespace Slicer::Gui:: diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 04bbe48b5d0..c4f55029b75 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -55,10 +55,12 @@ private: void *m_rdmmm; void register_window(); //void list_devices(); + void search_path(const std::string &path, const std::string &parent_path); + bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); #else void search_path(const std::string &path, const std::string &parent_path); bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); #endif }; }} -#endif \ No newline at end of file +#endif diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.mm b/src/slic3r/GUI/RemovableDriveManagerMM.mm index e4e324654ec..99abd73860f 100644 --- a/src/slic3r/GUI/RemovableDriveManagerMM.mm +++ b/src/slic3r/GUI/RemovableDriveManagerMM.mm @@ -1,37 +1,38 @@ #import "RemovableDriveManager.hpp" - +#import "RemovableDriveManagerMM.h" #import @implementation RemovableDriveManagerMM -namespace Slic3r { -namespace GUI { + -(instancetype) init { self = [super init]; if(self) { - [self add_unmount_observer] + [self add_unmount_observer]; } return self; } -(void) on_device_unmount: (NSNotification*) notification { NSLog(@"on device change"); - RemovableDriveManager::get_instance().update(); + Slic3r::GUI::RemovableDriveManager::get_instance().update(); } -(void) add_unmount_observer { + NSLog(@"add unmount observer"); [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(on_device_unmount:) name:NSWorkspaceDidUnmountNotification object:nil]; } - +namespace Slic3r { +namespace GUI { void RemovableDriveManager::register_window() { m_rdmmm = nullptr; m_rdmmm = [[RemovableDriveManagerMM alloc] init]; } - +}}//namespace Slicer::GUI /* -(void) RemovableDriveManager::list_devices() @@ -65,4 +66,5 @@ void RemovableDriveManager::register_window() } } */ -}}//namespace Slicer::GUI \ No newline at end of file + +@end From 69242b43946ae4955267a1af9cdf28c8c600b136 Mon Sep 17 00:00:00 2001 From: Slic3rPE Date: Tue, 10 Dec 2019 11:35:39 +0100 Subject: [PATCH 080/123] macos list devices --- src/slic3r/GUI/RemovableDriveManager.cpp | 4 +- src/slic3r/GUI/RemovableDriveManager.hpp | 4 +- src/slic3r/GUI/RemovableDriveManagerMM.h | 4 +- src/slic3r/GUI/RemovableDriveManagerMM.mm | 65 +++++++++++++---------- 4 files changed, 42 insertions(+), 35 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 8145c90760b..50e2b6359c4 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -218,11 +218,11 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP #else void RemovableDriveManager::search_for_drives() { - /* + #if __APPLE__ list_devices(); #endif -*/ + m_current_drives.clear(); m_current_drives.reserve(26); diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index c4f55029b75..7109bbd0708 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -39,7 +39,7 @@ public: void reset_last_save_path(); void print(); private: - RemovableDriveManager():m_drives_count(0),m_last_update(0),m_last_save_path(""){} + RemovableDriveManager():m_drives_count(0),m_last_update(0),m_last_save_path(""),m_rdmmm(nullptr){} void search_for_drives(); void check_and_notify(); std::string get_drive_from_path(const std::string& path);//returns drive path (same as path in DriveData) if exists otherwise empty string "" @@ -54,7 +54,7 @@ private: #elif __APPLE__ void *m_rdmmm; void register_window(); - //void list_devices(); + void list_devices(); void search_path(const std::string &path, const std::string &parent_path); bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); #else diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.h b/src/slic3r/GUI/RemovableDriveManagerMM.h index 8f783c2d2a9..4a5fa2515ed 100644 --- a/src/slic3r/GUI/RemovableDriveManagerMM.h +++ b/src/slic3r/GUI/RemovableDriveManagerMM.h @@ -5,5 +5,5 @@ -(instancetype) init; -(void) add_unmount_observer; -(void) on_device_unmount: (NSNotification*) notification; - -@end \ No newline at end of file +-(void) list_dev; +@end diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.mm b/src/slic3r/GUI/RemovableDriveManagerMM.mm index 99abd73860f..7e8b56c59b0 100644 --- a/src/slic3r/GUI/RemovableDriveManagerMM.mm +++ b/src/slic3r/GUI/RemovableDriveManagerMM.mm @@ -25,6 +25,36 @@ NSLog(@"add unmount observer"); [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(on_device_unmount:) name:NSWorkspaceDidUnmountNotification object:nil]; } +-(void) list_dev +{ + NSLog(@"---"); + NSArray* devices = [[NSWorkspace sharedWorkspace] mountedRemovableMedia]; + for (NSString* volumePath in devices) + { + NSLog(@"@", volumePath); + } + NSLog(@"--"); + //removable here means CD not USB :/ + NSArray* listOfMedia = [[NSWorkspace sharedWorkspace] mountedLocalVolumePaths]; + NSLog(@"%@", listOfMedia); + + for (NSString* volumePath in listOfMedia) + { + BOOL isRemovable = NO; + BOOL isWritable = NO; + BOOL isUnmountable = NO; + NSString* description = [NSString string]; + NSString* type = [NSString string]; + + BOOL result = [[NSWorkspace sharedWorkspace] getFileSystemInfoForPath:volumePath + isRemovable:&isRemovable + isWritable:&isWritable + isUnmountable:&isUnmountable + description:&description + type:&type]; + NSLog(@"Result:%i Volume: %@, Removable:%i, W:%i, Unmountable:%i, Desc:%@, type:%@", result, volumePath, isRemovable, isWritable, isUnmountable, description, type); + } +} namespace Slic3r { namespace GUI { void RemovableDriveManager::register_window() @@ -32,39 +62,16 @@ void RemovableDriveManager::register_window() m_rdmmm = nullptr; m_rdmmm = [[RemovableDriveManagerMM alloc] init]; } +void RemovableDriveManager::list_devices() +{ + if(m_rdmmm == nullptr) + return; + [m_rdmmm list_dev]; +} }}//namespace Slicer::GUI /* --(void) RemovableDriveManager::list_devices() -{ - NSLog(@"---"); - NSArray* devices = [[NSWorkspace sharedWorkspace] mountedRemovableMedia]; - for (NSString* volumePath in listOfMedia) - { - NSLog(@"@", volumePath); - } - NSLog(@"--"); - //removable here means CD not USB :/ - NSArray* listOfMedia = [[NSWorkspace sharedWorkspace] mountedLocalVolumePaths]; - NSLog(@"%@", listOfMedia); - for (NSString* volumePath in listOfMedia) - { - BOOL isRemovable = NO; - BOOL isWritable = NO; - BOOL isUnmountable = NO; - NSString* description = [NSString string]; - NSString* type = [NSString string]; - - BOOL result = [[NSWorkspace sharedWorkspace] getFileSystemInfoForPath:volumePath - isRemovable:&isRemovable - isWritable:&isWritable - isUnmountable:&isUnmountable - description:&description - type:&type]; - NSLog(@"Result:%i Volume: %@, Removable:%i, W:%i, Unmountable:%i, Desc:%@, type:%@", result, volumePath, isRemovable, isWritable, isUnmountable, description, type); - } -} */ @end From 50a2c7ee8d2ae1e642173ce6faaba9e4f20ee6f3 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 10 Dec 2019 14:10:47 +0100 Subject: [PATCH 081/123] macos better wrapper --- src/slic3r/GUI/RemovableDriveManager.cpp | 50 +++++++++-------- src/slic3r/GUI/RemovableDriveManager.hpp | 33 ++++++++--- src/slic3r/GUI/RemovableDriveManagerMM.h | 2 +- src/slic3r/GUI/RemovableDriveManagerMM.mm | 68 +++++++++++------------ 4 files changed, 87 insertions(+), 66 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 50e2b6359c4..763113ea2cf 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -220,9 +220,11 @@ void RemovableDriveManager::search_for_drives() { #if __APPLE__ - list_devices(); -#endif - + if(m_rdmmm) + { + m_rdmmm->list_devices(); + } +#else m_current_drives.clear(); m_current_drives.reserve(26); @@ -273,6 +275,7 @@ void RemovableDriveManager::search_for_drives() } //std::cout << "found drives:" <pw_name == username) - { - std::string name = basename(globbuf.gl_pathv[i]); - m_current_drives.push_back(DriveData(name,globbuf.gl_pathv[i])); - } - } - } + } }else { @@ -310,7 +296,27 @@ void RemovableDriveManager::search_path(const std::string &path,const std::strin globfree(&globbuf); } - +void RemovableDriveManager::inspect_file(const std::string &path, const std::string &parent_path) +{ + //if not same file system - could be removable drive + if(!compare_filesystem_id(globbuf.gl_pathv[i], parent_path)) + { + //user id + struct stat buf; + stat(globbuf.gl_pathv[i],&buf); + uid_t uid = buf.st_uid; + std::string username(std::getenv("USER")); + struct passwd *pw = getpwuid(uid); + if(pw != 0) + { + if(pw->pw_name == username) + { + std::string name = basename(globbuf.gl_pathv[i]); + m_current_drives.push_back(DriveData(name,globbuf.gl_pathv[i])); + } + } + } +} bool RemovableDriveManager::compare_filesystem_id(const std::string &path_a, const std::string &path_b) { struct stat buf; diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 7109bbd0708..202680328eb 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -39,7 +39,11 @@ public: void reset_last_save_path(); void print(); private: - RemovableDriveManager():m_drives_count(0),m_last_update(0),m_last_save_path(""),m_rdmmm(nullptr){} +#if __APPLE__ + RemovableDriveManager():m_drives_count(0),m_last_update(0),m_last_save_path(""),m_rdmmm(new RemovableDriveManagerMM()){} +#else + RemovableDriveManager() : m_drives_count(0), m_last_update(0), m_last_save_path(""){} +#endif void search_for_drives(); void check_and_notify(); std::string get_drive_from_path(const std::string& path);//returns drive path (same as path in DriveData) if exists otherwise empty string "" @@ -51,16 +55,27 @@ private: #if _WIN32 void register_window(); //INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); -#elif __APPLE__ - void *m_rdmmm; - void register_window(); - void list_devices(); - void search_path(const std::string &path, const std::string &parent_path); - bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); #else - void search_path(const std::string &path, const std::string &parent_path); - bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); +#if __APPLE__ + RemovableDriveManagerMM * m_rdmmm; + #endif + void search_path(const std::string &path, const std::string &parent_path); + void inspect_file(const std::string &path, const std::string &parent_path); + bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); #endif }; +#if __APPLE__ +class RemovableDriveManagerMM +{ +public: + RemovableDriveManagerMM(); + ~RemovableDriveManagerMM(); + register_window(); + list_devices(); +private: + RemovableDriveManagerMMImpl *m_imp; + friend void RemovableDriveManager::inspect_file(const std::string &path, const std::string &parent_path); +}; +#endif }} #endif diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.h b/src/slic3r/GUI/RemovableDriveManagerMM.h index 4a5fa2515ed..29994154546 100644 --- a/src/slic3r/GUI/RemovableDriveManagerMM.h +++ b/src/slic3r/GUI/RemovableDriveManagerMM.h @@ -5,5 +5,5 @@ -(instancetype) init; -(void) add_unmount_observer; -(void) on_device_unmount: (NSNotification*) notification; --(void) list_dev; +-(NSArray*) list_dev; @end diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.mm b/src/slic3r/GUI/RemovableDriveManagerMM.mm index 7e8b56c59b0..25fa6da0916 100644 --- a/src/slic3r/GUI/RemovableDriveManagerMM.mm +++ b/src/slic3r/GUI/RemovableDriveManagerMM.mm @@ -10,8 +10,7 @@ { self = [super init]; if(self) - { - [self add_unmount_observer]; + { } return self; } @@ -25,48 +24,49 @@ NSLog(@"add unmount observer"); [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(on_device_unmount:) name:NSWorkspaceDidUnmountNotification object:nil]; } --(void) list_dev +-(NSArray*) list_dev { - NSLog(@"---"); NSArray* devices = [[NSWorkspace sharedWorkspace] mountedRemovableMedia]; for (NSString* volumePath in devices) { - NSLog(@"@", volumePath); - } - NSLog(@"--"); - //removable here means CD not USB :/ - NSArray* listOfMedia = [[NSWorkspace sharedWorkspace] mountedLocalVolumePaths]; - NSLog(@"%@", listOfMedia); + NSLog(@"%@", volumePath); + } + return devices; - for (NSString* volumePath in listOfMedia) - { - BOOL isRemovable = NO; - BOOL isWritable = NO; - BOOL isUnmountable = NO; - NSString* description = [NSString string]; - NSString* type = [NSString string]; - - BOOL result = [[NSWorkspace sharedWorkspace] getFileSystemInfoForPath:volumePath - isRemovable:&isRemovable - isWritable:&isWritable - isUnmountable:&isUnmountable - description:&description - type:&type]; - NSLog(@"Result:%i Volume: %@, Removable:%i, W:%i, Unmountable:%i, Desc:%@, type:%@", result, volumePath, isRemovable, isWritable, isUnmountable, description, type); - } } namespace Slic3r { namespace GUI { -void RemovableDriveManager::register_window() -{ - m_rdmmm = nullptr; - m_rdmmm = [[RemovableDriveManagerMM alloc] init]; +struct RemovableDriveManagerMMImpl{ + RemovableDriveManagerMM * wrap; } -void RemovableDriveManager::list_devices() +RemovableDriveManagerMM():impl(new RemovableDriveManagerMMImpl){ + impl->wrap = [[RemovableDriveManagerMM alloc] init]; +} +RemovableDriveManagerMM::~RemovableDriveManagerMM() { - if(m_rdmmm == nullptr) - return; - [m_rdmmm list_dev]; + if(impl) + { + [impl->wrap release]; + } +} +void RDMMMWrapper::register_window() +{ + if(impl->wrap) + { + [impl->wrap add_unmount_observer]; + } +} +void RDMMMWrapper::list_devices() +{ + if(impl->wrap) + { + NSArray* devices = [impl->wrap list_dev]; + for (NSString* volumePath in devices) + { + NSLog(@"%@", volumePath); + Slic3r::GUI::RemovableDriveManager::get_instance().inspect_file(std::string([volumePath UTF8String]), "/Volumes"); + } + } } }}//namespace Slicer::GUI From 40ee3d8fa242b70ba3bbce1eef5c3eeddc11d910 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 10 Dec 2019 17:31:27 +0100 Subject: [PATCH 082/123] Implemented "Disconnect" button --- src/slic3r/GUI/Plater.cpp | 41 ++++++++++++++++++++++++++++++++------- src/slic3r/GUI/Plater.hpp | 1 + 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index b8b2f45e8b0..7b5cef4ca48 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -700,6 +700,7 @@ struct Sidebar::priv wxButton *btn_export_gcode; wxButton *btn_reslice; wxButton *btn_send_gcode; + ScalableButton *btn_disconnect; priv(Plater *plater) : plater(plater) {} ~priv(); @@ -848,22 +849,39 @@ Sidebar::Sidebar(Plater *parent) // Buttons underneath the scrolled area - auto init_btn = [this](wxButton **btn, wxString label) { + auto init_btn = [this](wxButton **btn, wxString label, const std::string icon_name = "", wxString tooltip = wxEmptyString) { *btn = new wxButton(this, wxID_ANY, label, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); (*btn)->SetFont(wxGetApp().bold_font()); + (*btn)->SetToolTip(tooltip); + + if (!icon_name.empty()) + (*btn)->SetBitmap(create_scaled_bitmap(this, icon_name)); }; - init_btn(&p->btn_send_gcode, _(L("Send to printer"))); + init_btn(&p->btn_send_gcode, /*_(L("Send to printer"))*/"", "export_gcode", _(L("Send to printer"))); p->btn_send_gcode->Hide(); init_btn(&p->btn_export_gcode, _(L("Export G-code")) + dots); init_btn(&p->btn_reslice, _(L("Slice now"))); + + p->btn_disconnect = new ScalableButton(this, wxID_ANY, "revert_all_", "", + wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT); + p->btn_disconnect->Hide(); + p->btn_disconnect->SetToolTip(_(L("Remove device"))); + enable_buttons(false); auto *btns_sizer = new wxBoxSizer(wxVERTICAL); + + auto* complect_btns_sizer = new wxBoxSizer(wxHORIZONTAL); + complect_btns_sizer->Add(p->btn_export_gcode, 1, wxEXPAND); + complect_btns_sizer->Add(p->btn_send_gcode, 0, wxEXPAND); + complect_btns_sizer->Add(p->btn_disconnect); + btns_sizer->Add(p->btn_reslice, 0, wxEXPAND | wxTOP, margin_5); - btns_sizer->Add(p->btn_send_gcode, 0, wxEXPAND | wxTOP, margin_5); - btns_sizer->Add(p->btn_export_gcode, 0, wxEXPAND | wxTOP, margin_5); + btns_sizer->Add(complect_btns_sizer, 0, wxEXPAND | wxTOP, margin_5); +// btns_sizer->Add(p->btn_send_gcode, 0, wxEXPAND | wxTOP, margin_5); +// btns_sizer->Add(p->btn_export_gcode, 0, wxEXPAND | wxTOP, margin_5); auto *sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(p->scrolled, 1, wxEXPAND); @@ -882,6 +900,9 @@ Sidebar::Sidebar(Plater *parent) p->plater->select_view_3D("Preview"); }); p->btn_send_gcode->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->send_gcode(); }); + p->btn_disconnect->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { + // #dk_FIXME + }); } Sidebar::~Sidebar() {} @@ -1255,11 +1276,13 @@ void Sidebar::enable_buttons(bool enable) p->btn_reslice->Enable(enable); p->btn_export_gcode->Enable(enable); p->btn_send_gcode->Enable(enable); + p->btn_disconnect->Enable(enable); } bool Sidebar::show_reslice(bool show) const { return p->btn_reslice->Show(show); } bool Sidebar::show_export(bool show) const { return p->btn_export_gcode->Show(show); } bool Sidebar::show_send(bool show) const { return p->btn_send_gcode->Show(show); } +bool Sidebar::show_disconnect(bool show)const { return p->btn_disconnect->Show(show); } bool Sidebar::is_multifilament() { @@ -4125,20 +4148,24 @@ void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const wxWindowUpdateLocker noUpdater(sidebar); const auto prin_host_opt = config->option("print_host"); const bool send_gcode_shown = prin_host_opt != nullptr && !prin_host_opt->value.empty(); + + const bool disconnect_shown = true; // #dk_FIXME // when a background processing is ON, export_btn and/or send_btn are showing if (wxGetApp().app_config->get("background_processing") == "1") { if (sidebar->show_reslice(false) | sidebar->show_export(true) | - sidebar->show_send(send_gcode_shown)) + sidebar->show_send(send_gcode_shown) | + sidebar->show_disconnect(disconnect_shown)) sidebar->Layout(); } else { if (sidebar->show_reslice(is_ready_to_slice) | sidebar->show_export(!is_ready_to_slice) | - sidebar->show_send(send_gcode_shown && !is_ready_to_slice)) + sidebar->show_send(send_gcode_shown && !is_ready_to_slice) | + sidebar->show_disconnect(disconnect_shown && !is_ready_to_slice)) sidebar->Layout(); } } @@ -4379,7 +4406,7 @@ void Sidebar::set_btn_label(const ActionButtonType btn_type, const wxString& lab { case ActionButtonType::abReslice: p->btn_reslice->SetLabelText(label); break; case ActionButtonType::abExport: p->btn_export_gcode->SetLabelText(label); break; - case ActionButtonType::abSendGCode: p->btn_send_gcode->SetLabelText(label); break; + case ActionButtonType::abSendGCode: /*p->btn_send_gcode->SetLabelText(label);*/ break; } } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 33140c4f5d7..528d6529719 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -119,6 +119,7 @@ public: bool show_reslice(bool show) const; bool show_export(bool show) const; bool show_send(bool show) const; + bool show_disconnect(bool show)const; bool is_multifilament(); void update_mode(); From 364617de89082b5d5916f850d8d2abc5896a7277 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 10 Dec 2019 14:41:49 +0100 Subject: [PATCH 083/123] fix --- src/slic3r/GUI/RemovableDriveManager.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 763113ea2cf..c5dca1bd554 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -231,9 +231,10 @@ void RemovableDriveManager::search_for_drives() //search /media/* folder search_path("/media/*", "/media"); +/* //search /Volumes/* folder (OSX) search_path("/Volumes/*", "/Volumes"); - +*/ std::string path(std::getenv("USER")); std::string pp(path); //std::cout << "user: "<< path << "\n"; @@ -286,7 +287,7 @@ void RemovableDriveManager::search_path(const std::string &path,const std::strin { for(size_t i = 0; i < globbuf.gl_pathc; i++) { - + inspect_file(globbuf.gl_pathv[i], parent_path); } }else { @@ -299,11 +300,11 @@ void RemovableDriveManager::search_path(const std::string &path,const std::strin void RemovableDriveManager::inspect_file(const std::string &path, const std::string &parent_path) { //if not same file system - could be removable drive - if(!compare_filesystem_id(globbuf.gl_pathv[i], parent_path)) + if(!compare_filesystem_id(path, parent_path)) { //user id struct stat buf; - stat(globbuf.gl_pathv[i],&buf); + stat(path.c_str(), &buf); uid_t uid = buf.st_uid; std::string username(std::getenv("USER")); struct passwd *pw = getpwuid(uid); @@ -311,8 +312,8 @@ void RemovableDriveManager::inspect_file(const std::string &path, const std::str { if(pw->pw_name == username) { - std::string name = basename(globbuf.gl_pathv[i]); - m_current_drives.push_back(DriveData(name,globbuf.gl_pathv[i])); + std::string name = basename(const_cast(path.c_str())); + m_current_drives.push_back(DriveData(name,path)); } } } From 57c9f1456fd10973771dca88e989330c9a0c8e2e Mon Sep 17 00:00:00 2001 From: Slic3rPE Date: Wed, 11 Dec 2019 10:16:32 +0100 Subject: [PATCH 084/123] macos better wrapper --- src/slic3r/GUI/RemovableDriveManager.hpp | 29 +++++++++++++---------- src/slic3r/GUI/RemovableDriveManagerMM.mm | 21 +++++++--------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 202680328eb..cbf6f53aac5 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -6,6 +6,10 @@ namespace Slic3r { namespace GUI { +class RDMMMWrapper; +#if __APPLE__ + + struct DriveData { std::string name; @@ -57,25 +61,24 @@ private: //INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); #else #if __APPLE__ - RemovableDriveManagerMM * m_rdmmm; + RDMMMWrapper * m_rdmmm; #endif void search_path(const std::string &path, const std::string &parent_path); void inspect_file(const std::string &path, const std::string &parent_path); bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); #endif }; -#if __APPLE__ -class RemovableDriveManagerMM -{ -public: - RemovableDriveManagerMM(); - ~RemovableDriveManagerMM(); - register_window(); - list_devices(); -private: - RemovableDriveManagerMMImpl *m_imp; - friend void RemovableDriveManager::inspect_file(const std::string &path, const std::string &parent_path); -}; + class RDMMMWrapper + { + public: + RDMMMWrapper(); + ~RDMMMWrapper(); + void register_window(); + void list_devices(); + private: + void *m_imp; + friend void RemovableDriveManager::inspect_file(const std::string &path, const std::string &parent_path); + }; #endif }} #endif diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.mm b/src/slic3r/GUI/RemovableDriveManagerMM.mm index 25fa6da0916..269a2255b0c 100644 --- a/src/slic3r/GUI/RemovableDriveManagerMM.mm +++ b/src/slic3r/GUI/RemovableDriveManagerMM.mm @@ -36,31 +36,28 @@ } namespace Slic3r { namespace GUI { -struct RemovableDriveManagerMMImpl{ - RemovableDriveManagerMM * wrap; +RDMMMWrapper::RDMMMWrapper():m_imp(nullptr){ + m_imp = [[RemovableDriveManagerMM alloc] init]; } -RemovableDriveManagerMM():impl(new RemovableDriveManagerMMImpl){ - impl->wrap = [[RemovableDriveManagerMM alloc] init]; -} -RemovableDriveManagerMM::~RemovableDriveManagerMM() +RDMMMWrapper::~RDMMMWrapper() { - if(impl) + if(m_imp) { - [impl->wrap release]; + [m_imp release]; } } void RDMMMWrapper::register_window() { - if(impl->wrap) + if(m_imp) { - [impl->wrap add_unmount_observer]; + [m_imp add_unmount_observer]; } } void RDMMMWrapper::list_devices() { - if(impl->wrap) + if(m_imp) { - NSArray* devices = [impl->wrap list_dev]; + NSArray* devices = [m_imp list_dev]; for (NSString* volumePath in devices) { NSLog(@"%@", volumePath); From 9548d4413b75dd2dc6dd9230b08d549f4e965729 Mon Sep 17 00:00:00 2001 From: Slic3rPE Date: Wed, 11 Dec 2019 11:00:47 +0100 Subject: [PATCH 085/123] macos better wrapper --- src/slic3r/GUI/RemovableDriveManager.cpp | 12 ++++++- src/slic3r/GUI/RemovableDriveManager.hpp | 40 ++++++++++++----------- src/slic3r/GUI/RemovableDriveManagerMM.mm | 4 --- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index c5dca1bd554..164b6e38aa8 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -391,13 +391,23 @@ std::string RemovableDriveManager::get_drive_from_path(const std::string& path) return ""; } #endif + +RemovableDriveManager::RemovableDriveManager(): + m_drives_count(0), + m_last_update(0), + m_last_save_path(""), +#if __APPLE__ + m_rdmmm(new RDMMMWrapper()) +#endif +{} + void RemovableDriveManager::init() { add_callback([](void) { RemovableDriveManager::get_instance().print(); }); #if _WIN32 register_window(); #elif __APPLE__ - register_window(); + m_rdmmm->register_window(); #endif update(); } diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index cbf6f53aac5..a5027a5adf8 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -6,9 +6,9 @@ namespace Slic3r { namespace GUI { -class RDMMMWrapper; #if __APPLE__ - +class RDMMMWrapper; +#endif struct DriveData { @@ -18,6 +18,9 @@ struct DriveData }; class RemovableDriveManager { +#if __APPLE__ +friend class RDMMMWrapper; +#endif public: static RemovableDriveManager& get_instance() { @@ -42,12 +45,9 @@ public: bool is_last_drive_removed_with_update(const long time = 0); // param as update() void reset_last_save_path(); void print(); + private: -#if __APPLE__ - RemovableDriveManager():m_drives_count(0),m_last_update(0),m_last_save_path(""),m_rdmmm(new RemovableDriveManagerMM()){} -#else - RemovableDriveManager() : m_drives_count(0), m_last_update(0), m_last_save_path(""){} -#endif + RemovableDriveManager(); void search_for_drives(); void check_and_notify(); std::string get_drive_from_path(const std::string& path);//returns drive path (same as path in DriveData) if exists otherwise empty string "" @@ -64,21 +64,23 @@ private: RDMMMWrapper * m_rdmmm; #endif void search_path(const std::string &path, const std::string &parent_path); - void inspect_file(const std::string &path, const std::string &parent_path); bool compare_filesystem_id(const std::string &path_a, const std::string &path_b); + void inspect_file(const std::string &path, const std::string &parent_path); #endif }; - class RDMMMWrapper - { - public: - RDMMMWrapper(); - ~RDMMMWrapper(); - void register_window(); - void list_devices(); - private: - void *m_imp; - friend void RemovableDriveManager::inspect_file(const std::string &path, const std::string &parent_path); - }; + +#if __APPLE__ +class RDMMMWrapper +{ +public: + RDMMMWrapper(); + ~RDMMMWrapper(); + void register_window(); + void list_devices(); +protected: + void *m_imp; + //friend void RemovableDriveManager::inspect_file(const std::string &path, const std::string &parent_path); +}; #endif }} #endif diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.mm b/src/slic3r/GUI/RemovableDriveManagerMM.mm index 269a2255b0c..d32b7b278e5 100644 --- a/src/slic3r/GUI/RemovableDriveManagerMM.mm +++ b/src/slic3r/GUI/RemovableDriveManagerMM.mm @@ -27,10 +27,6 @@ -(NSArray*) list_dev { NSArray* devices = [[NSWorkspace sharedWorkspace] mountedRemovableMedia]; - for (NSString* volumePath in devices) - { - NSLog(@"%@", volumePath); - } return devices; } From 1f7a371e20f0d198b0939a2bc2347eaa15422af9 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 11 Dec 2019 11:00:23 +0100 Subject: [PATCH 086/123] Added missed icon --- resources/icons/revert_all_.svg | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 resources/icons/revert_all_.svg diff --git a/resources/icons/revert_all_.svg b/resources/icons/revert_all_.svg new file mode 100644 index 00000000000..fe8de635db4 --- /dev/null +++ b/resources/icons/revert_all_.svg @@ -0,0 +1,9 @@ + + + + + Svg Vector Icons : http://www.onlinewebfonts.com/icon + + + + \ No newline at end of file From 02c42d14a33184be105a02f74b318be32ef7e3b8 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 11 Dec 2019 12:28:51 +0100 Subject: [PATCH 087/123] eject button functionality --- src/slic3r/GUI/Plater.cpp | 19 ++++++++++++++++++- src/slic3r/GUI/Plater.hpp | 2 ++ src/slic3r/GUI/RemovableDriveManager.cpp | 22 +++++++++------------- src/slic3r/GUI/RemovableDriveManager.hpp | 8 +++++--- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 7b5cef4ca48..ed60066e54c 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -902,6 +902,7 @@ Sidebar::Sidebar(Plater *parent) p->btn_send_gcode->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->send_gcode(); }); p->btn_disconnect->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { // #dk_FIXME + p->plater->eject_drive(); }); } @@ -4149,7 +4150,7 @@ void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const const auto prin_host_opt = config->option("print_host"); const bool send_gcode_shown = prin_host_opt != nullptr && !prin_host_opt->value.empty(); - const bool disconnect_shown = true; // #dk_FIXME + const bool disconnect_shown = !(RemovableDriveManager::get_instance().is_last_drive_removed()); // #dk_FIXME // when a background processing is ON, export_btn and/or send_btn are showing if (wxGetApp().app_config->get("background_processing") == "1") @@ -4992,6 +4993,22 @@ void Plater::send_gcode() } } +void Plater::eject_drive() +{ + if (GUI::RemovableDriveManager::get_instance().update()) + { + RemovableDriveManager::get_instance().erase_callbacks(); + RemovableDriveManager::get_instance().add_callback(std::bind(&Plater::drive_ejected_callback, this)); + RemovableDriveManager::get_instance().eject_drive(RemovableDriveManager::get_instance().get_last_drive_path()); + } +} +void Plater::drive_ejected_callback() +{ + p->show_action_buttons(false); +} + + + void Plater::take_snapshot(const std::string &snapshot_name) { p->take_snapshot(snapshot_name); } void Plater::take_snapshot(const wxString &snapshot_name) { p->take_snapshot(snapshot_name); } void Plater::suppress_snapshots() { p->suppress_snapshots(); } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 528d6529719..d9a9af37636 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -202,6 +202,8 @@ public: void suppress_background_process(const bool stop_background_process) ; void fix_through_netfabb(const int obj_idx, const int vol_idx = -1); void send_gcode(); + void eject_drive(); + void drive_ejected_callback(); void take_snapshot(const std::string &snapshot_name); void take_snapshot(const wxString &snapshot_name); diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 164b6e38aa8..1a964f889dc 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -395,9 +395,9 @@ std::string RemovableDriveManager::get_drive_from_path(const std::string& path) RemovableDriveManager::RemovableDriveManager(): m_drives_count(0), m_last_update(0), - m_last_save_path(""), + m_last_save_path("") #if __APPLE__ - m_rdmmm(new RDMMMWrapper()) + , m_rdmmm(new RDMMMWrapper()) #endif {} @@ -411,7 +411,7 @@ void RemovableDriveManager::init() #endif update(); } -bool RemovableDriveManager::update(const long time) +bool RemovableDriveManager::update(const long time, bool check) { if(time != 0) //time = 0 is forced update { @@ -425,7 +425,7 @@ bool RemovableDriveManager::update(const long time) } } search_for_drives(); - check_and_notify(); + if(check)check_and_notify(); return !m_current_drives.empty(); } @@ -444,13 +444,7 @@ bool RemovableDriveManager::is_drive_mounted(const std::string &path) std::string RemovableDriveManager::get_last_drive_path() { - if (!m_current_drives.empty()) - { - if (m_last_save_path != "") - return m_last_save_path; - return m_current_drives.back().path; - } - return ""; + return m_last_save_path; } std::vector RemovableDriveManager::get_all_drives() { @@ -495,11 +489,13 @@ bool RemovableDriveManager::is_last_drive_removed() { return true; } - return !is_drive_mounted(m_last_save_path); + bool r = !is_drive_mounted(m_last_save_path); + if (r) reset_last_save_path(); + return r; } bool RemovableDriveManager::is_last_drive_removed_with_update(const long time) { - update(time); + update(time, false); return is_last_drive_removed(); } void RemovableDriveManager::reset_last_save_path() diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index a5027a5adf8..f412940010f 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -32,7 +32,7 @@ public: //update() searches for removable devices, returns false if empty. void init(); - bool update(const long time = 0); //time = 0 is forced update, time expects wxGetLocalTime() + bool update(const long time = 0, bool check = true); //time = 0 is forced update, time expects wxGetLocalTime() bool is_drive_mounted(const std::string &path); void eject_drive(const std::string &path); std::string get_last_drive_path(); @@ -41,9 +41,8 @@ public: void add_callback(std::function callback); // callback will notify only if device with last save path was removed void erase_callbacks(); // erases all callbacks added by add_callback() void set_last_save_path(const std::string &path); - bool is_last_drive_removed(); //if we dont need info about this drive, call reset_last_save_path(); + bool is_last_drive_removed(); bool is_last_drive_removed_with_update(const long time = 0); // param as update() - void reset_last_save_path(); void print(); private: @@ -51,11 +50,14 @@ private: void search_for_drives(); void check_and_notify(); std::string get_drive_from_path(const std::string& path);//returns drive path (same as path in DriveData) if exists otherwise empty string "" + void reset_last_save_path(); + std::vector m_current_drives; std::vector> m_callbacks; size_t m_drives_count; long m_last_update; std::string m_last_save_path; + #if _WIN32 void register_window(); //INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); From c63351a19e6f08c8bd262b8946ca4d7150d7c6f0 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 11 Dec 2019 14:53:28 +0100 Subject: [PATCH 088/123] eject button functionality --- src/slic3r/GUI/GUI_App.cpp | 2 +- src/slic3r/GUI/Plater.cpp | 6 +++--- src/slic3r/GUI/RemovableDriveManager.cpp | 24 +++++++++++++++++------ src/slic3r/GUI/RemovableDriveManager.hpp | 5 +++-- src/slic3r/GUI/RemovableDriveManagerMM.mm | 2 +- 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index e13701f61da..786a5901e5c 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -275,7 +275,7 @@ bool GUI_App::on_init_inner() this->obj_manipul()->update_if_dirty(); - //RemovableDriveManager::get_instance().update(wxGetLocalTime()); + RemovableDriveManager::get_instance().update(wxGetLocalTime(), true); // Preset updating & Configwizard are done after the above initializations, diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index ed60066e54c..7edf657be44 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4694,7 +4694,7 @@ void Plater::export_gcode() { if (!RemovableDriveManager::get_instance().is_path_on_removable_drive(start_dir)) { - start_dir = RemovableDriveManager::get_instance().get_last_drive_path(); + start_dir = RemovableDriveManager::get_instance().get_drive_path(); } } wxFileDialog dlg(this, (printer_technology() == ptFFF) ? _(L("Save G-code file as:")) : _(L("Save SL1 file as:")), @@ -4995,11 +4995,11 @@ void Plater::send_gcode() void Plater::eject_drive() { - if (GUI::RemovableDriveManager::get_instance().update()) + if (GUI::RemovableDriveManager::get_instance().update(0, true)) { RemovableDriveManager::get_instance().erase_callbacks(); RemovableDriveManager::get_instance().add_callback(std::bind(&Plater::drive_ejected_callback, this)); - RemovableDriveManager::get_instance().eject_drive(RemovableDriveManager::get_instance().get_last_drive_path()); + RemovableDriveManager::get_instance().eject_drive(RemovableDriveManager::get_instance().get_last_save_path()); } } void Plater::drive_ejected_callback() diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 1a964f889dc..49bf59e11fe 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -198,15 +198,16 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP DEVICE_NOTIFY_WINDOW_HANDLE // type of recipient handle ); break; + /* case WM_DEVICECHANGE: { if(wParam == DBT_DEVICEREMOVECOMPLETE) { - std::cout << "WM_DEVICECHANGE\n"; - RemovableDriveManager::get_instance().update(); +- RemovableDriveManager::get_instance().update(0, true); } } break; + */ default: // Send all other messages on to the default windows handler. lRet = DefWindowProc(hWnd, message, wParam, lParam); @@ -403,7 +404,7 @@ RemovableDriveManager::RemovableDriveManager(): void RemovableDriveManager::init() { - add_callback([](void) { RemovableDriveManager::get_instance().print(); }); + //add_callback([](void) { RemovableDriveManager::get_instance().print(); }); #if _WIN32 register_window(); #elif __APPLE__ @@ -441,8 +442,18 @@ bool RemovableDriveManager::is_drive_mounted(const std::string &path) } return false; } - -std::string RemovableDriveManager::get_last_drive_path() +std::string RemovableDriveManager::get_drive_path() +{ + if (m_current_drives.size() == 0) + { + reset_last_save_path(); + return ""; + } + if (m_last_save_path != "") + return m_last_save_path; + return m_current_drives.back().path; +} +std::string RemovableDriveManager::get_last_save_path() { return m_last_save_path; } @@ -456,7 +467,7 @@ void RemovableDriveManager::check_and_notify() if(m_drives_count != m_current_drives.size()) { //std::cout<<" vs "<< m_current_drives.size(); - if(m_drives_count > m_current_drives.size() && m_last_save_path != "" && !is_drive_mounted(m_last_save_path)) + if(m_callbacks.size() != 0 && m_drives_count > m_current_drives.size() && m_last_save_path != "" && !is_drive_mounted(m_last_save_path)) { for (auto it = m_callbacks.begin(); it != m_callbacks.end(); ++it) { @@ -485,6 +496,7 @@ void RemovableDriveManager::set_last_save_path(const std::string& path) } bool RemovableDriveManager::is_last_drive_removed() { + m_drives_count = m_current_drives.size(); if(m_last_save_path == "") { return true; diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index f412940010f..49df4148270 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -32,10 +32,11 @@ public: //update() searches for removable devices, returns false if empty. void init(); - bool update(const long time = 0, bool check = true); //time = 0 is forced update, time expects wxGetLocalTime() + bool update(const long time = 0, bool check = false); //time = 0 is forced update, time expects wxGetLocalTime() bool is_drive_mounted(const std::string &path); void eject_drive(const std::string &path); - std::string get_last_drive_path(); + std::string get_last_save_path(); + std::string get_drive_path(); std::vector get_all_drives(); bool is_path_on_removable_drive(const std::string &path); void add_callback(std::function callback); // callback will notify only if device with last save path was removed diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.mm b/src/slic3r/GUI/RemovableDriveManagerMM.mm index d32b7b278e5..7a1108541a5 100644 --- a/src/slic3r/GUI/RemovableDriveManagerMM.mm +++ b/src/slic3r/GUI/RemovableDriveManagerMM.mm @@ -17,7 +17,7 @@ -(void) on_device_unmount: (NSNotification*) notification { NSLog(@"on device change"); - Slic3r::GUI::RemovableDriveManager::get_instance().update(); + Slic3r::GUI::RemovableDriveManager::get_instance().update(0,true); } -(void) add_unmount_observer { From 1d25e220064c3abaa3c597b338cac9121f87c234 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 11 Dec 2019 15:02:20 +0100 Subject: [PATCH 089/123] eject button functionality --- src/slic3r/GUI/Plater.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 7edf657be44..8a96ac4d424 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4709,7 +4709,9 @@ void Plater::export_gcode() fs::path path = into_path(dlg.GetPath()); wxGetApp().app_config->update_last_output_dir(path.parent_path().string()); output_path = std::move(path); - RemovableDriveManager::get_instance().set_last_save_path(output_path.string()); + RemovableDriveManager::get_instance().update(0, true); + RemovableDriveManager::get_instance().set_last_save_path(output_path.string()); + } if (! output_path.empty()) p->export_gcode(std::move(output_path), PrintHostJob()); From 727a0a017990b978471d9fe276751a7d18a7abf8 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 11 Dec 2019 17:02:12 +0100 Subject: [PATCH 090/123] eject button functionality --- src/slic3r/GUI/GUI_App.cpp | 2 +- src/slic3r/GUI/RemovableDriveManager.cpp | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 786a5901e5c..b83ecbedc88 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -275,7 +275,7 @@ bool GUI_App::on_init_inner() this->obj_manipul()->update_if_dirty(); - RemovableDriveManager::get_instance().update(wxGetLocalTime(), true); + //RemovableDriveManager::get_instance().update(wxGetLocalTime(), true); // Preset updating & Configwizard are done after the above initializations, diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 49bf59e11fe..dc8469d9a24 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -96,14 +96,16 @@ void RemovableDriveManager::eject_drive(const std::string &path) return; } DWORD deviceControlRetVal(0); + DeviceIoControl(handle, FSCTL_LOCK_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); + DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); - CloseHandle(handle); if (error == 0) { + CloseHandle(handle); std::cerr << "Ejecting " << mpath << " failed " << deviceControlRetVal << " " << GetLastError() << " \n"; return; } - + CloseHandle(handle); m_current_drives.erase(it); break; @@ -198,7 +200,7 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP DEVICE_NOTIFY_WINDOW_HANDLE // type of recipient handle ); break; - /* + case WM_DEVICECHANGE: { if(wParam == DBT_DEVICEREMOVECOMPLETE) @@ -207,7 +209,7 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP } } break; - */ + default: // Send all other messages on to the default windows handler. lRet = DefWindowProc(hWnd, message, wParam, lParam); From 3275870cae8e900ee15e9963e92b7fb28d32f25b Mon Sep 17 00:00:00 2001 From: Slic3rPE Date: Wed, 11 Dec 2019 16:59:26 +0100 Subject: [PATCH 091/123] macos eject --- src/slic3r/GUI/RemovableDriveManager.cpp | 5 +++++ src/slic3r/GUI/RemovableDriveManager.hpp | 1 + src/slic3r/GUI/RemovableDriveManagerMM.mm | 4 ++++ 3 files changed, 10 insertions(+) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index dc8469d9a24..afe5ee73939 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -427,6 +427,10 @@ bool RemovableDriveManager::update(const long time, bool check) return false; // return value shouldnt matter if update didnt run } } + if(check) + { + m_rdmmm->log("update"); + } search_for_drives(); if(check)check_and_notify(); return !m_current_drives.empty(); @@ -468,6 +472,7 @@ void RemovableDriveManager::check_and_notify() //std::cout<<"drives count: "<log("drives count not same"); //std::cout<<" vs "<< m_current_drives.size(); if(m_callbacks.size() != 0 && m_drives_count > m_current_drives.size() && m_last_save_path != "" && !is_drive_mounted(m_last_save_path)) { diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 49df4148270..9eea355f79a 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -80,6 +80,7 @@ public: ~RDMMMWrapper(); void register_window(); void list_devices(); + void log(const std::string &msg); protected: void *m_imp; //friend void RemovableDriveManager::inspect_file(const std::string &path, const std::string &parent_path); diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.mm b/src/slic3r/GUI/RemovableDriveManagerMM.mm index 7a1108541a5..45bd21bcfaa 100644 --- a/src/slic3r/GUI/RemovableDriveManagerMM.mm +++ b/src/slic3r/GUI/RemovableDriveManagerMM.mm @@ -61,6 +61,10 @@ void RDMMMWrapper::list_devices() } } } +void RDMMMWrapper::log(const std::string &msg) +{ + NSLog(@"%s", msg.c_str()); +} }}//namespace Slicer::GUI /* From 1a1b84798e0d838907cc6519135558010d252512 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 11 Dec 2019 17:42:56 +0100 Subject: [PATCH 092/123] eject button functionality --- src/slic3r/GUI/Plater.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 8a96ac4d424..d5786491100 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4997,12 +4997,11 @@ void Plater::send_gcode() void Plater::eject_drive() { - if (GUI::RemovableDriveManager::get_instance().update(0, true)) - { - RemovableDriveManager::get_instance().erase_callbacks(); - RemovableDriveManager::get_instance().add_callback(std::bind(&Plater::drive_ejected_callback, this)); - RemovableDriveManager::get_instance().eject_drive(RemovableDriveManager::get_instance().get_last_save_path()); - } + RemovableDriveManager::get_instance().update(0, true); + RemovableDriveManager::get_instance().erase_callbacks(); + RemovableDriveManager::get_instance().add_callback(std::bind(&Plater::drive_ejected_callback, this)); + RemovableDriveManager::get_instance().eject_drive(RemovableDriveManager::get_instance().get_last_save_path()); + } void Plater::drive_ejected_callback() { From e1b118d75e3422ce6662f9aee1904f0b58727d24 Mon Sep 17 00:00:00 2001 From: Slic3rPE Date: Wed, 11 Dec 2019 17:39:34 +0100 Subject: [PATCH 093/123] macos eject --- src/slic3r/GUI/RemovableDriveManager.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index afe5ee73939..ab2dd10eb20 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -221,15 +221,17 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP #else void RemovableDriveManager::search_for_drives() { - + + m_current_drives.clear(); + m_current_drives.reserve(26); + #if __APPLE__ if(m_rdmmm) { m_rdmmm->list_devices(); } #else - m_current_drives.clear(); - m_current_drives.reserve(26); + //search /media/* folder search_path("/media/*", "/media"); From b238399d9f4eda9f33895d878da52b66568fa7ef Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 11 Dec 2019 18:30:03 +0100 Subject: [PATCH 094/123] linux eject --- src/slic3r/GUI/GUI_App.cpp | 6 +++--- src/slic3r/GUI/RemovableDriveManager.cpp | 9 ++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index b83ecbedc88..c9ed88f84a3 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -274,9 +274,9 @@ bool GUI_App::on_init_inner() this->obj_manipul()->update_if_dirty(); - - //RemovableDriveManager::get_instance().update(wxGetLocalTime(), true); - +#if __linux__ + RemovableDriveManager::get_instance().update(wxGetLocalTime(), true); +#endif // Preset updating & Configwizard are done after the above initializations, // and after MainFrame is created & shown. diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index ab2dd10eb20..d5f2244095f 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -429,10 +429,6 @@ bool RemovableDriveManager::update(const long time, bool check) return false; // return value shouldnt matter if update didnt run } } - if(check) - { - m_rdmmm->log("update"); - } search_for_drives(); if(check)check_and_notify(); return !m_current_drives.empty(); @@ -474,7 +470,7 @@ void RemovableDriveManager::check_and_notify() //std::cout<<"drives count: "<log("drives count not same"); + //m_rdmmm->log("drives count not same"); //std::cout<<" vs "<< m_current_drives.size(); if(m_callbacks.size() != 0 && m_drives_count > m_current_drives.size() && m_last_save_path != "" && !is_drive_mounted(m_last_save_path)) { @@ -505,13 +501,16 @@ void RemovableDriveManager::set_last_save_path(const std::string& path) } bool RemovableDriveManager::is_last_drive_removed() { + std::cout<<"is last: "< Date: Thu, 12 Dec 2019 10:48:33 +0100 Subject: [PATCH 095/123] eject button after export --- src/slic3r/GUI/GUI_App.cpp | 2 +- src/slic3r/GUI/Plater.cpp | 9 +++++---- src/slic3r/GUI/RemovableDriveManager.cpp | 8 ++++---- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index c9ed88f84a3..f601cd4bc75 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -274,7 +274,7 @@ bool GUI_App::on_init_inner() this->obj_manipul()->update_if_dirty(); -#if __linux__ +#if !__APPLE__ RemovableDriveManager::get_instance().update(wxGetLocalTime(), true); #endif diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index d5786491100..eb5f6d4850a 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4158,7 +4158,7 @@ void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const if (sidebar->show_reslice(false) | sidebar->show_export(true) | sidebar->show_send(send_gcode_shown) | - sidebar->show_disconnect(disconnect_shown)) + sidebar->show_disconnect(false/*disconnect_shown*/)) sidebar->Layout(); } else @@ -4709,12 +4709,13 @@ void Plater::export_gcode() fs::path path = into_path(dlg.GetPath()); wxGetApp().app_config->update_last_output_dir(path.parent_path().string()); output_path = std::move(path); - RemovableDriveManager::get_instance().update(0, true); - RemovableDriveManager::get_instance().set_last_save_path(output_path.string()); - } if (! output_path.empty()) + { + RemovableDriveManager::get_instance().update(0, true); + RemovableDriveManager::get_instance().set_last_save_path(output_path.string()); p->export_gcode(std::move(output_path), PrintHostJob()); + } } diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index d5f2244095f..7ab34204bc2 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -410,7 +410,7 @@ void RemovableDriveManager::init() { //add_callback([](void) { RemovableDriveManager::get_instance().print(); }); #if _WIN32 - register_window(); + //register_window(); #elif __APPLE__ m_rdmmm->register_window(); #endif @@ -501,16 +501,16 @@ void RemovableDriveManager::set_last_save_path(const std::string& path) } bool RemovableDriveManager::is_last_drive_removed() { - std::cout<<"is last: "< Date: Thu, 12 Dec 2019 14:56:30 +0100 Subject: [PATCH 096/123] button show after write --- src/slic3r/GUI/Plater.cpp | 8 ++++-- src/slic3r/GUI/RemovableDriveManager.cpp | 35 +++--------------------- src/slic3r/GUI/RemovableDriveManager.hpp | 4 +-- 3 files changed, 10 insertions(+), 37 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index eb5f6d4850a..cefe31e90b6 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3179,6 +3179,7 @@ void Plater::priv::update_fff_scene() this->preview->reload_print(); // In case this was MM print, wipe tower bounding box on 3D tab might need redrawing with exact depth: view3D->reload_scene(true); + show_action_buttons(false); } void Plater::priv::update_sla_scene() @@ -4158,7 +4159,7 @@ void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const if (sidebar->show_reslice(false) | sidebar->show_export(true) | sidebar->show_send(send_gcode_shown) | - sidebar->show_disconnect(false/*disconnect_shown*/)) + sidebar->show_disconnect(disconnect_shown)) sidebar->Layout(); } else @@ -4712,9 +4713,10 @@ void Plater::export_gcode() } if (! output_path.empty()) { - RemovableDriveManager::get_instance().update(0, true); - RemovableDriveManager::get_instance().set_last_save_path(output_path.string()); + std::string path = output_path.string(); p->export_gcode(std::move(output_path), PrintHostJob()); + RemovableDriveManager::get_instance().update(0, true); + RemovableDriveManager::get_instance().set_last_save_path(path); } } diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 7ab34204bc2..cd360b580f3 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -24,9 +24,6 @@ GUID WceusbshGUID = { 0x25dbce51, 0x6c8f, 0x4a72, namespace Slic3r { namespace GUI { -//std::vector RemovableDriveManager::m_current_drives; -//std::vector> RemovableDriveManager::m_callbacks; - #if _WIN32 INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); @@ -42,7 +39,6 @@ void RemovableDriveManager::search_for_drives() std::string path (1,(char)('A' + i)); path+=":"; UINT drive_type = GetDriveTypeA(path.c_str()); - //std::cout << "found drive" << (char)('A' + i) << ": type:" < 0) { path += "\\"; @@ -74,12 +69,9 @@ void RemovableDriveManager::search_for_drives() } } } - //std::cout << "found drives:" << m_current_drives.size() << "\n"; } void RemovableDriveManager::eject_drive(const std::string &path) { - - //if (!update() || !is_drive_mounted(path)) if(m_current_drives.empty()) return; for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) @@ -88,7 +80,6 @@ void RemovableDriveManager::eject_drive(const std::string &path) { std::string mpath = "\\\\.\\" + path; mpath = mpath.substr(0, mpath.size() - 1); - //std::cout << "Ejecting " << mpath << "\n"; HANDLE handle = CreateFileA(mpath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); if (handle == INVALID_HANDLE_VALUE) { @@ -138,7 +129,7 @@ std::string RemovableDriveManager::get_drive_from_path(const std::string& path) } void RemovableDriveManager::register_window() { - std::cout << "Registering for device notification\n"; + //creates new unvisible window that is recieving callbacks from system WNDCLASSEX wndClass; wndClass.cbSize = sizeof(WNDCLASSEX); wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; @@ -181,9 +172,6 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP LRESULT lRet = 1; static HDEVNOTIFY hDeviceNotify; - static HWND hEditWnd; - static ULONGLONG msgCount = 0; - switch (message) { case WM_CREATE: @@ -194,11 +182,7 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; NotificationFilter.dbcc_classguid = WceusbshGUID; - hDeviceNotify = RegisterDeviceNotification( - hWnd, // events recipient - &NotificationFilter, // type of device - DEVICE_NOTIFY_WINDOW_HANDLE // type of recipient handle - ); + hDeviceNotify = RegisterDeviceNotification(hWnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE); break; case WM_DEVICECHANGE: @@ -280,7 +264,6 @@ void RemovableDriveManager::search_for_drives() } - //std::cout << "found drives:" < RemovableDriveManager::get_all_drives() } void RemovableDriveManager::check_and_notify() { - //std::cout<<"drives count: "<log("drives count not same"); - //std::cout<<" vs "<< m_current_drives.size(); if(m_callbacks.size() != 0 && m_drives_count > m_current_drives.size() && m_last_save_path != "" && !is_drive_mounted(m_last_save_path)) { for (auto it = m_callbacks.begin(); it != m_callbacks.end(); ++it) @@ -481,7 +461,6 @@ void RemovableDriveManager::check_and_notify() } m_drives_count = m_current_drives.size(); } - //std::cout<<"\n"; } void RemovableDriveManager::add_callback(std::function callback) { @@ -522,10 +501,4 @@ void RemovableDriveManager::reset_last_save_path() { m_last_save_path = ""; } - -void RemovableDriveManager::print() -{ - //std::cout << "Removed Device: "<<(int)is_last_drive_removed()<<"\n"; - std::cout << "notified\n"; -} -}}//namespace Slicer::Gui:: +}}//namespace Slicer::Gui diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 9eea355f79a..b4fc71e2656 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -32,7 +32,7 @@ public: //update() searches for removable devices, returns false if empty. void init(); - bool update(const long time = 0, bool check = false); //time = 0 is forced update, time expects wxGetLocalTime() + bool update(const long time = 0,const bool check = false); //time = 0 is forced update, time expects wxGetLocalTime() bool is_drive_mounted(const std::string &path); void eject_drive(const std::string &path); std::string get_last_save_path(); @@ -44,8 +44,6 @@ public: void set_last_save_path(const std::string &path); bool is_last_drive_removed(); bool is_last_drive_removed_with_update(const long time = 0); // param as update() - void print(); - private: RemovableDriveManager(); void search_for_drives(); From e14ffed68b936e4a901de3a99bc058bbeef60aff Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 12 Dec 2019 15:43:14 +0100 Subject: [PATCH 097/123] button show after write --- src/slic3r/GUI/Plater.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index cefe31e90b6..910de4722f6 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3179,7 +3179,7 @@ void Plater::priv::update_fff_scene() this->preview->reload_print(); // In case this was MM print, wipe tower bounding box on 3D tab might need redrawing with exact depth: view3D->reload_scene(true); - show_action_buttons(false); + } void Plater::priv::update_sla_scene() @@ -3578,6 +3578,8 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt) default: break; } + show_action_buttons(false); + if (canceled) { if (wxGetApp().get_mode() == comSimple) sidebar->set_btn_label(ActionButtonType::abReslice, "Slice now"); From 43a6b22ea029ebaea3f837150c66f999b463c19e Mon Sep 17 00:00:00 2001 From: David Kocik Date: Fri, 13 Dec 2019 11:52:08 +0100 Subject: [PATCH 098/123] comments --- src/slic3r/GUI/RemovableDriveManager.cpp | 24 ++++++++++++++++++---- src/slic3r/GUI/RemovableDriveManager.hpp | 26 ++++++++++++++++-------- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index cd360b580f3..02681b7daf2 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -30,7 +30,7 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP void RemovableDriveManager::search_for_drives() { m_current_drives.clear(); - m_current_drives.reserve(26); + //get logical drives flags by letter in alphabetical order DWORD drives_mask = GetLogicalDrives(); for (size_t i = 0; i < 26; i++) { @@ -39,6 +39,7 @@ void RemovableDriveManager::search_for_drives() std::string path (1,(char)('A' + i)); path+=":"; UINT drive_type = GetDriveTypeA(path.c_str()); + // DRIVE_REMOVABLE on W are sd cards and usb thumbnails (not usb harddrives) if (drive_type == DRIVE_REMOVABLE) { // get name of drive @@ -51,10 +52,12 @@ void RemovableDriveManager::search_for_drives() BOOL error = GetVolumeInformationW(wpath.c_str(), &volume_name[0], sizeof(volume_name), NULL, NULL, NULL, &file_system_name[0], sizeof(file_system_name)); if(error != 0) { + /* if (volume_name == L"") { volume_name = L"REMOVABLE DRIVE"; } + */ if (file_system_name != L"") { ULARGE_INTEGER free_space; @@ -78,6 +81,7 @@ void RemovableDriveManager::eject_drive(const std::string &path) { if ((*it).path == path) { + // get handle to device std::string mpath = "\\\\.\\" + path; mpath = mpath.substr(0, mpath.size() - 1); HANDLE handle = CreateFileA(mpath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); @@ -87,8 +91,12 @@ void RemovableDriveManager::eject_drive(const std::string &path) return; } DWORD deviceControlRetVal(0); + //these 3 commands should eject device safely but they dont, the device does disappear from file explorer but the "device was safely remove" notification doesnt trigger. + //sd cards does trigger WM_DEVICECHANGE messege, usb drives dont + DeviceIoControl(handle, FSCTL_LOCK_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); + // some implemenatations also calls IOCTL_STORAGE_MEDIA_REMOVAL here but it returns error to me BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); if (error == 0) { @@ -130,11 +138,12 @@ std::string RemovableDriveManager::get_drive_from_path(const std::string& path) void RemovableDriveManager::register_window() { //creates new unvisible window that is recieving callbacks from system + // structure to register WNDCLASSEX wndClass; wndClass.cbSize = sizeof(WNDCLASSEX); wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wndClass.hInstance = reinterpret_cast(GetModuleHandle(0)); - wndClass.lpfnWndProc = reinterpret_cast(WinProcCallback); + wndClass.lpfnWndProc = reinterpret_cast(WinProcCallback);//this is callback wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 0; wndClass.hIcon = LoadIcon(0, IDI_APPLICATION); @@ -169,6 +178,9 @@ void RemovableDriveManager::register_window() INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { + // here we need to catch messeges about device removal + // problem is that when ejecting usb (how is it implemented above) there is no messege dispached. Only after physical removal of the device. + //uncomment register_window() in init() to register and comment update() in GUI_App.cpp (only for windows!) to stop recieving periodical updates LRESULT lRet = 1; static HDEVNOTIFY hDeviceNotify; @@ -187,6 +199,7 @@ INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP case WM_DEVICECHANGE: { + // here is the important if(wParam == DBT_DEVICEREMOVECOMPLETE) { - RemovableDriveManager::get_instance().update(0, true); @@ -207,9 +220,9 @@ void RemovableDriveManager::search_for_drives() { m_current_drives.clear(); - m_current_drives.reserve(26); #if __APPLE__ + // if on macos obj-c class will enumerate if(m_rdmmm) { m_rdmmm->list_devices(); @@ -287,6 +300,8 @@ void RemovableDriveManager::search_path(const std::string &path,const std::strin } void RemovableDriveManager::inspect_file(const std::string &path, const std::string &parent_path) { + //confirms if the file is removable drive and adds it to vector + //if not same file system - could be removable drive if(!compare_filesystem_id(path, parent_path)) { @@ -335,7 +350,8 @@ void RemovableDriveManager::eject_drive(const std::string &path) } } std::cout<<"Ejecting "<<(*it).name<<" from "<< correct_path<<"\n"; - +// there is no usable command in c++ so terminal command is used instead +// but neither triggers "succesful safe removal messege" std::string command = ""; #if __APPLE__ command = "diskutil unmount "; diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index b4fc71e2656..ac1645df7bf 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -29,26 +29,34 @@ public: } RemovableDriveManager(RemovableDriveManager const&) = delete; void operator=(RemovableDriveManager const&) = delete; - - //update() searches for removable devices, returns false if empty. + //call only once. on apple register for unmnount callbacks. on windows register for device notification is prepared but not called (eject usb drive on widnows doesnt trigger the callback, sdc ard does), also enumerates devices for first time so init shoud be called on linux too. void init(); - bool update(const long time = 0,const bool check = false); //time = 0 is forced update, time expects wxGetLocalTime() + //update() searches for removable devices, returns false if empty. /time = 0 is forced update, time expects wxGetLocalTime() + bool update(const long time = 0,const bool check = false); bool is_drive_mounted(const std::string &path); void eject_drive(const std::string &path); + //returns path to last drive which was used, if none was used, returns device that was enumerated last std::string get_last_save_path(); + //returns path to last drive which was used, if none was used, returns empty string std::string get_drive_path(); std::vector get_all_drives(); bool is_path_on_removable_drive(const std::string &path); - void add_callback(std::function callback); // callback will notify only if device with last save path was removed - void erase_callbacks(); // erases all callbacks added by add_callback() + // callback will notify only if device with last save path was removed + void add_callback(std::function callback); + // erases all callbacks added by add_callback() + void erase_callbacks(); + // marks one of the eveices in vector as last used void set_last_save_path(const std::string &path); bool is_last_drive_removed(); - bool is_last_drive_removed_with_update(const long time = 0); // param as update() + // param as update() + bool is_last_drive_removed_with_update(const long time = 0); private: RemovableDriveManager(); void search_for_drives(); + //triggers callbacks if last used drive was removed void check_and_notify(); - std::string get_drive_from_path(const std::string& path);//returns drive path (same as path in DriveData) if exists otherwise empty string "" + //returns drive path (same as path in DriveData) if exists otherwise empty string "" + std::string get_drive_from_path(const std::string& path); void reset_last_save_path(); std::vector m_current_drives; @@ -58,8 +66,8 @@ private: std::string m_last_save_path; #if _WIN32 + //registers for notifications by creating invisible window void register_window(); - //INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); #else #if __APPLE__ RDMMMWrapper * m_rdmmm; @@ -69,7 +77,7 @@ private: void inspect_file(const std::string &path, const std::string &parent_path); #endif }; - +// apple wrapper for RemovableDriveManagerMM which searches for drives and/or ejects them #if __APPLE__ class RDMMMWrapper { From 6a5abaea97239e10b3947e79d91bd20f009d9312 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Fri, 13 Dec 2019 13:04:09 +0100 Subject: [PATCH 099/123] comments --- src/slic3r/GUI/Plater.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 910de4722f6..52255d17634 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3577,7 +3577,7 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt) break; default: break; } - + //added to show disconnect_button after writing show_action_buttons(false); if (canceled) { From 43c545853f690bb61e575b3fe48a66090da780f1 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 26 Nov 2019 14:19:29 +0100 Subject: [PATCH 100/123] removable drive manager - Windows part --- src/slic3r/GUI/AppConfig.cpp | 8 ++ src/slic3r/GUI/RemovableDriveManager.cpp | 150 +++++++++++++++++++++++ src/slic3r/GUI/RemovableDriveManager.hpp | 33 +++++ 3 files changed, 191 insertions(+) diff --git a/src/slic3r/GUI/AppConfig.cpp b/src/slic3r/GUI/AppConfig.cpp index 70558225135..f24bde2426b 100644 --- a/src/slic3r/GUI/AppConfig.cpp +++ b/src/slic3r/GUI/AppConfig.cpp @@ -21,6 +21,7 @@ #include #include "I18N.hpp" +#include "RemovableDriveManager.hpp" namespace Slic3r { @@ -357,7 +358,14 @@ void AppConfig::update_skein_dir(const std::string &dir) std::string AppConfig::get_last_output_dir(const std::string &alt) const { +<<<<<<< HEAD +======= + if (GUI::RemovableDriveManager::getInstance().update()) + { + return GUI::RemovableDriveManager::getInstance().getLastDrivePath(); + } +>>>>>>> removable drive manager - Windows part const auto it = m_storage.find(""); if (it != m_storage.end()) { const auto it2 = it->second.find("last_output_path"); diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 02681b7daf2..ba5ab50727b 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -1,4 +1,5 @@ #include "RemovableDriveManager.hpp" +<<<<<<< HEAD #include #include "boost/nowide/convert.hpp" @@ -66,10 +67,72 @@ void RemovableDriveManager::search_for_drives() { path += "\\"; m_current_drives.push_back(DriveData(boost::nowide::narrow(volume_name), path)); +======= + +#include +#include +#include +#include + +//#include +//#include "libslic3r/Utils.hpp" + +DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, + 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED); + +namespace Slic3r { +namespace GUI { + +std::vector RemovableDriveManager::currentDrives; + +bool RemovableDriveManager::update() +{ + searchForDrives(currentDrives); + return !currentDrives.empty(); +} +void RemovableDriveManager::searchForDrives(std::vector& newDrives) +{ + newDrives.clear(); + newDrives.reserve(26); + DWORD drivesMask = GetLogicalDrives(); + for (size_t i = 0; i < 26; i++) + { + if(drivesMask & (1 << i)) + { + std::string path (1,(char)('A' + i)); + path+=":"; + UINT driveType = GetDriveTypeA(path.c_str()); + //std::cout << "found drive" << (char)('A' + i) << ": type:" < 0) + { + newDrives.push_back(DriveData(volumeName, path)); +>>>>>>> removable drive manager - Windows part } } } } +<<<<<<< HEAD } } } @@ -518,3 +581,90 @@ void RemovableDriveManager::reset_last_save_path() m_last_save_path = ""; } }}//namespace Slicer::Gui +======= + else if(driveType == 3)//disks and usb drives + { + } + } + } + +} + +void RemovableDriveManager::updateCurrentDrives(const std::vector& newDrives) +{ + currentDrives.clear(); + currentDrives.reserve(26); + for (auto it = newDrives.begin(); it != newDrives.end(); ++it) + { + currentDrives.push_back(*it); + } +} +void RemovableDriveManager::printDrivesToLog() +{ + //std::cout<<"current drives:"<< currentDrives.size() <<"\n"; + for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + { + //BOOST_LOG_TRIVIAL(trace) << boost::format("found disk %1%:") % ('A' + i); + //std::cout << /*std::string((*it).name.begin(), (*it).name.end()) << "(" << */(*it).path << ":/, "; + } + //std::cout << "\n"; +} +bool RemovableDriveManager::isDriveMounted(std::string path) +{ + for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + { + if ((*it).path == path) + { + return true; + } + } + return false; +} +void RemovableDriveManager::ejectDrive(std::string path) +{ + if (!update() || !isDriveMounted(path)) + return; + + path = "\\\\.\\"+path; + HANDLE handle = CreateFileA(path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); + if(handle == INVALID_HANDLE_VALUE) + { + std::cerr << "Ejecting " << path << " failed " << GetLastError() << " \n"; + return; + } + DWORD deviceControlRetVal(0); + BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0,nullptr , 0, &deviceControlRetVal, nullptr); + CloseHandle(handle); + if(error != 0) + std::cout << "Ejected " << path << "\n"; + else + std::cerr << "Ejecting " << path << " failed "<< deviceControlRetVal << " " << GetLastError() <<" \n"; + + for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + { + if ((*it).path == path) + { + currentDrives.erase(it); + break; + } + } +} +std::string RemovableDriveManager::getLastDrivePath() +{ + if (!currentDrives.empty()) + { + return currentDrives.back().path; + } + return ""; +} +void RemovableDriveManager::getAllDrives(std::vector& drives) +{ + drives.clear(); + drives.reserve(26); + for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + { + drives.push_back(*it); + } +} +}} +>>>>>>> removable drive manager - Windows part diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index ac1645df7bf..a5abde72d0f 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -6,6 +6,7 @@ namespace Slic3r { namespace GUI { +<<<<<<< HEAD #if __APPLE__ class RDMMMWrapper; #endif @@ -23,12 +24,25 @@ friend class RDMMMWrapper; #endif public: static RemovableDriveManager& get_instance() +======= +struct DriveData +{ + std::wstring name; + std::string path; + DriveData(std::wstring n, std::string p):name(n),path(p){} +}; +class RemovableDriveManager +{ +public: + static RemovableDriveManager& getInstance() +>>>>>>> removable drive manager - Windows part { static RemovableDriveManager instance; return instance; } RemovableDriveManager(RemovableDriveManager const&) = delete; void operator=(RemovableDriveManager const&) = delete; +<<<<<<< HEAD //call only once. on apple register for unmnount callbacks. on windows register for device notification is prepared but not called (eject usb drive on widnows doesnt trigger the callback, sdc ard does), also enumerates devices for first time so init shoud be called on linux too. void init(); //update() searches for removable devices, returns false if empty. /time = 0 is forced update, time expects wxGetLocalTime() @@ -94,3 +108,22 @@ protected: #endif }} #endif +======= + + //update() searches for removable devices, returns false if empty. + static bool update(); + static bool isDriveMounted(std::string path); + static void ejectDrive(std::string path); + static std::string getLastDrivePath(); + static void getAllDrives(std::vector& drives); +private: + RemovableDriveManager(){} + static void searchForDrives(std::vector& newDrives); + static void printDrivesToLog(); + static void updateCurrentDrives(const std::vector& newDrives); + static std::vector currentDrives; + +}; +}} +#endif +>>>>>>> removable drive manager - Windows part From 84ad62d7aca3d10ac46937d747c80ea8cbe2c540 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 26 Nov 2019 15:52:18 +0100 Subject: [PATCH 101/123] removable drives manager linux part --- src/slic3r/GUI/RemovableDriveManager.cpp | 166 +++++++++++++++++------ src/slic3r/GUI/RemovableDriveManager.hpp | 10 +- 2 files changed, 132 insertions(+), 44 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index ba5ab50727b..e6133204549 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -69,27 +69,35 @@ void RemovableDriveManager::search_for_drives() m_current_drives.push_back(DriveData(boost::nowide::narrow(volume_name), path)); ======= -#include -#include + + #include #include -//#include -//#include "libslic3r/Utils.hpp" +#if _WIN32 +#include +#include DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED); +#else +//linux includes +#include +#include +#include +#include +#include +#endif namespace Slic3r { namespace GUI { std::vector RemovableDriveManager::currentDrives; -bool RemovableDriveManager::update() -{ - searchForDrives(currentDrives); - return !currentDrives.empty(); -} + + + +#if _WIN32 void RemovableDriveManager::searchForDrives(std::vector& newDrives) { newDrives.clear(); @@ -589,37 +597,6 @@ void RemovableDriveManager::reset_last_save_path() } } - -void RemovableDriveManager::updateCurrentDrives(const std::vector& newDrives) -{ - currentDrives.clear(); - currentDrives.reserve(26); - for (auto it = newDrives.begin(); it != newDrives.end(); ++it) - { - currentDrives.push_back(*it); - } -} -void RemovableDriveManager::printDrivesToLog() -{ - //std::cout<<"current drives:"<< currentDrives.size() <<"\n"; - for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) - { - //BOOST_LOG_TRIVIAL(trace) << boost::format("found disk %1%:") % ('A' + i); - //std::cout << /*std::string((*it).name.begin(), (*it).name.end()) << "(" << */(*it).path << ":/, "; - } - //std::cout << "\n"; -} -bool RemovableDriveManager::isDriveMounted(std::string path) -{ - for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) - { - if ((*it).path == path) - { - return true; - } - } - return false; -} void RemovableDriveManager::ejectDrive(std::string path) { if (!update() || !isDriveMounted(path)) @@ -649,6 +626,115 @@ void RemovableDriveManager::ejectDrive(std::string path) } } } +#else +void RemovableDriveManager::searchForDrives(std::vector& newDrives) +{ + struct stat buf; + std::string path(std::getenv("USER")); + std::string pp(path); + + newDrives.clear(); + newDrives.reserve(26); + + //search /media/* folder + stat("/media/",&buf); + std::cout << "/media ID: " <& newDrives,const std::string path, const dev_t parentDevID) +{ + glob_t globbuf; + globbuf.gl_offs = 2; + std::cout<<"searching "<& newDrives) +{ + currentDrives.clear(); + currentDrives.reserve(26); + for (auto it = newDrives.begin(); it != newDrives.end(); ++it) + { + currentDrives.push_back(*it); + } +} +bool RemovableDriveManager::isDriveMounted(std::string path) +{ + for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + { + if ((*it).path == path) + { + return true; + } + } + return false; +} + std::string RemovableDriveManager::getLastDrivePath() { if (!currentDrives.empty()) diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index a5abde72d0f..157f670b316 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -27,9 +27,9 @@ public: ======= struct DriveData { - std::wstring name; + std::string name; std::string path; - DriveData(std::wstring n, std::string p):name(n),path(p){} + DriveData(std::string n, std::string p):name(n),path(p){} }; class RemovableDriveManager { @@ -119,10 +119,12 @@ protected: private: RemovableDriveManager(){} static void searchForDrives(std::vector& newDrives); - static void printDrivesToLog(); static void updateCurrentDrives(const std::vector& newDrives); static std::vector currentDrives; - +#if _WIN32 +#else + static void searchPath(std::vector& newDrives,const std::string path, const dev_t parentDevID); +#endif }; }} #endif From 34239be561803b11ce8972ab79f0f69ae2ba3290 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 27 Nov 2019 11:33:36 +0100 Subject: [PATCH 102/123] refactoring --- src/slic3r/GUI/AppConfig.cpp | 2 +- src/slic3r/GUI/RemovableDriveManager.cpp | 118 +++++++++++------------ src/slic3r/GUI/RemovableDriveManager.hpp | 15 ++- 3 files changed, 64 insertions(+), 71 deletions(-) diff --git a/src/slic3r/GUI/AppConfig.cpp b/src/slic3r/GUI/AppConfig.cpp index f24bde2426b..9f294a3b605 100644 --- a/src/slic3r/GUI/AppConfig.cpp +++ b/src/slic3r/GUI/AppConfig.cpp @@ -363,7 +363,7 @@ std::string AppConfig::get_last_output_dir(const std::string &alt) const ======= if (GUI::RemovableDriveManager::getInstance().update()) { - return GUI::RemovableDriveManager::getInstance().getLastDrivePath(); + return GUI::RemovableDriveManager::getInstance().get_last_drive_path(); } >>>>>>> removable drive manager - Windows part const auto it = m_storage.find(""); diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index e6133204549..30f6c9b2902 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -1,5 +1,6 @@ #include "RemovableDriveManager.hpp" <<<<<<< HEAD +<<<<<<< HEAD #include #include "boost/nowide/convert.hpp" @@ -71,13 +72,16 @@ void RemovableDriveManager::search_for_drives() +======= +>>>>>>> refactoring #include #include - +#include "boost/nowide/convert.hpp" #if _WIN32 #include #include +#include DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED); #else @@ -92,16 +96,13 @@ DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, namespace Slic3r { namespace GUI { -std::vector RemovableDriveManager::currentDrives; - - - +std::vector RemovableDriveManager::m_current_drives; #if _WIN32 -void RemovableDriveManager::searchForDrives(std::vector& newDrives) +void RemovableDriveManager::search_for_drives() { - newDrives.clear(); - newDrives.reserve(26); + m_current_drives.clear(); + m_current_drives.reserve(26); DWORD drivesMask = GetLogicalDrives(); for (size_t i = 0; i < 26; i++) { @@ -134,8 +135,12 @@ void RemovableDriveManager::searchForDrives(std::vector& newDrives) //std::cout << std::string(volumeName.begin(), volumeName.end()) << " " << std::string(fileSystemName.begin(), fileSystemName.end()) << " " << freeSpace.QuadPart << "\n"; if (freeSpace.QuadPart > 0) { +<<<<<<< HEAD newDrives.push_back(DriveData(volumeName, path)); >>>>>>> removable drive manager - Windows part +======= + m_current_drives.push_back(DriveData(boost::nowide::narrow(volumeName), path)); +>>>>>>> refactoring } } } @@ -597,49 +602,51 @@ void RemovableDriveManager::reset_last_save_path() } } -void RemovableDriveManager::ejectDrive(std::string path) +void RemovableDriveManager::eject_drive(const std::string &path) { - if (!update() || !isDriveMounted(path)) - return; - path = "\\\\.\\"+path; - HANDLE handle = CreateFileA(path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); - if(handle == INVALID_HANDLE_VALUE) - { - std::cerr << "Ejecting " << path << " failed " << GetLastError() << " \n"; + //if (!update() || !is_drive_mounted(path)) + if(m_current_drives.empty()) return; - } - DWORD deviceControlRetVal(0); - BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0,nullptr , 0, &deviceControlRetVal, nullptr); - CloseHandle(handle); - if(error != 0) - std::cout << "Ejected " << path << "\n"; - else - std::cerr << "Ejecting " << path << " failed "<< deviceControlRetVal << " " << GetLastError() <<" \n"; - - for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) { if ((*it).path == path) { - currentDrives.erase(it); + std::string mpath = "\\\\.\\" + path; + HANDLE handle = CreateFileA(mpath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); + if (handle == INVALID_HANDLE_VALUE) + { + std::cerr << "Ejecting " << mpath << " failed " << GetLastError() << " \n"; + return; + } + DWORD deviceControlRetVal(0); + BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); + CloseHandle(handle); + if (error != 0) + std::cout << "Ejected " << mpath << "\n"; + else + std::cerr << "Ejecting " << mpath << " failed " << deviceControlRetVal << " " << GetLastError() << " \n"; + + + m_current_drives.erase(it); break; } } } #else -void RemovableDriveManager::searchForDrives(std::vector& newDrives) +void RemovableDriveManager::search_for_drives() { struct stat buf; std::string path(std::getenv("USER")); std::string pp(path); - newDrives.clear(); - newDrives.reserve(26); + m_current_drives.clear(); + m_current_Drives.reserve(26); //search /media/* folder stat("/media/",&buf); std::cout << "/media ID: " <& newDrives) stat(pp.c_str() ,&buf); std::cout << pp <<" ID: " <& newDrives,const std::string path, const dev_t parentDevID) +void RemovableDriveManager::search_path(const std::string &path,const dev_t &parentDevID) { glob_t globbuf; globbuf.gl_offs = 2; @@ -679,17 +686,17 @@ void RemovableDriveManager::searchPath(std::vector& newDrives,const s std::cout << buf.st_dev << "\n"; if(buf.st_dev != parentDevID)// not same file system { - newDrives.push_back(DriveData(name,globbuf.gl_pathv[i])); + m_current_drives.push_back(DriveData(name,globbuf.gl_pathv[i])); } } globfree(&globbuf); } -void RemovableDriveManager::ejectDrive(std::string path) +void RemovableDriveManager::eject_drive(const std::string &path) { - if (currentDrives.empty()) + if (m_current_drives.empty()) return; - for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) { if((*it).path == path) { @@ -700,7 +707,7 @@ void RemovableDriveManager::ejectDrive(std::string path) int errsv = errno; std::cerr<<"Ejecting failed Error "<< errsv<<"\n"; } - currentDrives.erase(it); + m_current_drives.erase(it); break; } @@ -710,22 +717,14 @@ void RemovableDriveManager::ejectDrive(std::string path) #endif bool RemovableDriveManager::update() { - searchForDrives(currentDrives); - return !currentDrives.empty(); + search_for_drives(); + return !m_current_drives.empty(); } -void RemovableDriveManager::updateCurrentDrives(const std::vector& newDrives) + +bool RemovableDriveManager::is_drive_mounted(const std::string &path) { - currentDrives.clear(); - currentDrives.reserve(26); - for (auto it = newDrives.begin(); it != newDrives.end(); ++it) - { - currentDrives.push_back(*it); - } -} -bool RemovableDriveManager::isDriveMounted(std::string path) -{ - for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) + for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) { if ((*it).path == path) { @@ -735,22 +734,17 @@ bool RemovableDriveManager::isDriveMounted(std::string path) return false; } -std::string RemovableDriveManager::getLastDrivePath() +std::string RemovableDriveManager::get_last_drive_path() { - if (!currentDrives.empty()) + if (!m_current_drives.empty()) { - return currentDrives.back().path; + return m_current_drives.back().path; } return ""; } -void RemovableDriveManager::getAllDrives(std::vector& drives) +std::vector RemovableDriveManager::get_all_drives() { - drives.clear(); - drives.reserve(26); - for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it) - { - drives.push_back(*it); - } + return m_current_drives; } }} >>>>>>> removable drive manager - Windows part diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 157f670b316..c001644460a 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -112,18 +112,17 @@ protected: //update() searches for removable devices, returns false if empty. static bool update(); - static bool isDriveMounted(std::string path); - static void ejectDrive(std::string path); - static std::string getLastDrivePath(); - static void getAllDrives(std::vector& drives); + static bool is_drive_mounted(const std::string &path); + static void eject_drive(const std::string &path); + static std::string get_last_drive_path(); + static std::vector get_all_drives(); private: RemovableDriveManager(){} - static void searchForDrives(std::vector& newDrives); - static void updateCurrentDrives(const std::vector& newDrives); - static std::vector currentDrives; + static void search_for_drives(); + static std::vector m_current_drives; #if _WIN32 #else - static void searchPath(std::vector& newDrives,const std::string path, const dev_t parentDevID); + static void search_path(const std::string &path, const dev_t &parentDevID); #endif }; }} From 04adeabea34014c1358b017b945590d5229db536 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 27 Nov 2019 13:30:45 +0100 Subject: [PATCH 103/123] check if last path is on rem drive --- src/slic3r/GUI/AppConfig.cpp | 5 +- src/slic3r/GUI/Plater.cpp | 8 + src/slic3r/GUI/RemovableDriveManager.cpp | 230 ----------------------- src/slic3r/GUI/RemovableDriveManager.hpp | 1 + 4 files changed, 13 insertions(+), 231 deletions(-) diff --git a/src/slic3r/GUI/AppConfig.cpp b/src/slic3r/GUI/AppConfig.cpp index 9f294a3b605..e27fa1be655 100644 --- a/src/slic3r/GUI/AppConfig.cpp +++ b/src/slic3r/GUI/AppConfig.cpp @@ -21,7 +21,6 @@ #include #include "I18N.hpp" -#include "RemovableDriveManager.hpp" namespace Slic3r { @@ -359,6 +358,7 @@ void AppConfig::update_skein_dir(const std::string &dir) std::string AppConfig::get_last_output_dir(const std::string &alt) const { <<<<<<< HEAD +<<<<<<< HEAD ======= if (GUI::RemovableDriveManager::getInstance().update()) @@ -366,6 +366,9 @@ std::string AppConfig::get_last_output_dir(const std::string &alt) const return GUI::RemovableDriveManager::getInstance().get_last_drive_path(); } >>>>>>> removable drive manager - Windows part +======= + +>>>>>>> check if last path is on rem drive const auto it = m_storage.find(""); if (it != m_storage.end()) { const auto it2 = it->second.find("last_output_path"); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 52255d17634..aff162401f8 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4693,11 +4693,19 @@ void Plater::export_gcode() } default_output_file = fs::path(Slic3r::fold_utf8_to_ascii(default_output_file.string())); auto start_dir = wxGetApp().app_config->get_last_output_dir(default_output_file.parent_path().string()); +<<<<<<< HEAD if (GUI::RemovableDriveManager::get_instance().update()) { if (!RemovableDriveManager::get_instance().is_path_on_removable_drive(start_dir)) { start_dir = RemovableDriveManager::get_instance().get_drive_path(); +======= + if (GUI::RemovableDriveManager::getInstance().update()) + { + if (!RemovableDriveManager::getInstance().is_path_on_removable_drive(start_dir)) + { + start_dir = RemovableDriveManager::getInstance().get_last_drive_path(); +>>>>>>> check if last path is on rem drive } } wxFileDialog dlg(this, (printer_technology() == ptFFF) ? _(L("Save G-code file as:")) : _(L("Save SL1 file as:")), diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 30f6c9b2902..02681b7daf2 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -1,6 +1,4 @@ #include "RemovableDriveManager.hpp" -<<<<<<< HEAD -<<<<<<< HEAD #include #include "boost/nowide/convert.hpp" @@ -68,84 +66,10 @@ void RemovableDriveManager::search_for_drives() { path += "\\"; m_current_drives.push_back(DriveData(boost::nowide::narrow(volume_name), path)); -======= - - - -======= ->>>>>>> refactoring -#include -#include -#include "boost/nowide/convert.hpp" - -#if _WIN32 -#include -#include -#include -DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, - 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED); -#else -//linux includes -#include -#include -#include -#include -#include -#endif - -namespace Slic3r { -namespace GUI { - -std::vector RemovableDriveManager::m_current_drives; - -#if _WIN32 -void RemovableDriveManager::search_for_drives() -{ - m_current_drives.clear(); - m_current_drives.reserve(26); - DWORD drivesMask = GetLogicalDrives(); - for (size_t i = 0; i < 26; i++) - { - if(drivesMask & (1 << i)) - { - std::string path (1,(char)('A' + i)); - path+=":"; - UINT driveType = GetDriveTypeA(path.c_str()); - //std::cout << "found drive" << (char)('A' + i) << ": type:" < 0) - { -<<<<<<< HEAD - newDrives.push_back(DriveData(volumeName, path)); ->>>>>>> removable drive manager - Windows part -======= - m_current_drives.push_back(DriveData(boost::nowide::narrow(volumeName), path)); ->>>>>>> refactoring } } } } -<<<<<<< HEAD } } } @@ -594,157 +518,3 @@ void RemovableDriveManager::reset_last_save_path() m_last_save_path = ""; } }}//namespace Slicer::Gui -======= - else if(driveType == 3)//disks and usb drives - { - } - } - } - -} -void RemovableDriveManager::eject_drive(const std::string &path) -{ - - //if (!update() || !is_drive_mounted(path)) - if(m_current_drives.empty()) - return; - for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) - { - if ((*it).path == path) - { - std::string mpath = "\\\\.\\" + path; - HANDLE handle = CreateFileA(mpath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); - if (handle == INVALID_HANDLE_VALUE) - { - std::cerr << "Ejecting " << mpath << " failed " << GetLastError() << " \n"; - return; - } - DWORD deviceControlRetVal(0); - BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); - CloseHandle(handle); - if (error != 0) - std::cout << "Ejected " << mpath << "\n"; - else - std::cerr << "Ejecting " << mpath << " failed " << deviceControlRetVal << " " << GetLastError() << " \n"; - - - m_current_drives.erase(it); - break; - } - } -} -#else -void RemovableDriveManager::search_for_drives() -{ - struct stat buf; - std::string path(std::getenv("USER")); - std::string pp(path); - - m_current_drives.clear(); - m_current_Drives.reserve(26); - - //search /media/* folder - stat("/media/",&buf); - std::cout << "/media ID: " < RemovableDriveManager::get_all_drives() -{ - return m_current_drives; -} -}} ->>>>>>> removable drive manager - Windows part diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index c001644460a..1e5d240f09c 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -116,6 +116,7 @@ protected: static void eject_drive(const std::string &path); static std::string get_last_drive_path(); static std::vector get_all_drives(); + static bool is_path_on_removable_drive(const std::string &path); private: RemovableDriveManager(){} static void search_for_drives(); From 1a5b9d86fc70cb79e166c1ad25f515c594b2e4f4 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 27 Nov 2019 14:30:10 +0100 Subject: [PATCH 104/123] prev commit linux part --- src/slic3r/GUI/AppConfig.cpp | 12 -------- src/slic3r/GUI/Plater.cpp | 8 ----- src/slic3r/GUI/RemovableDriveManager.cpp | 3 +- src/slic3r/GUI/RemovableDriveManager.hpp | 37 +----------------------- 4 files changed, 3 insertions(+), 57 deletions(-) diff --git a/src/slic3r/GUI/AppConfig.cpp b/src/slic3r/GUI/AppConfig.cpp index e27fa1be655..d33d945efb9 100644 --- a/src/slic3r/GUI/AppConfig.cpp +++ b/src/slic3r/GUI/AppConfig.cpp @@ -357,18 +357,6 @@ void AppConfig::update_skein_dir(const std::string &dir) std::string AppConfig::get_last_output_dir(const std::string &alt) const { -<<<<<<< HEAD -<<<<<<< HEAD - -======= - if (GUI::RemovableDriveManager::getInstance().update()) - { - return GUI::RemovableDriveManager::getInstance().get_last_drive_path(); - } ->>>>>>> removable drive manager - Windows part -======= - ->>>>>>> check if last path is on rem drive const auto it = m_storage.find(""); if (it != m_storage.end()) { const auto it2 = it->second.find("last_output_path"); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index aff162401f8..52255d17634 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4693,19 +4693,11 @@ void Plater::export_gcode() } default_output_file = fs::path(Slic3r::fold_utf8_to_ascii(default_output_file.string())); auto start_dir = wxGetApp().app_config->get_last_output_dir(default_output_file.parent_path().string()); -<<<<<<< HEAD if (GUI::RemovableDriveManager::get_instance().update()) { if (!RemovableDriveManager::get_instance().is_path_on_removable_drive(start_dir)) { start_dir = RemovableDriveManager::get_instance().get_drive_path(); -======= - if (GUI::RemovableDriveManager::getInstance().update()) - { - if (!RemovableDriveManager::getInstance().is_path_on_removable_drive(start_dir)) - { - start_dir = RemovableDriveManager::getInstance().get_last_drive_path(); ->>>>>>> check if last path is on rem drive } } wxFileDialog dlg(this, (printer_technology() == ptFFF) ? _(L("Save G-code file as:")) : _(L("Save SL1 file as:")), diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 02681b7daf2..77a387aaf58 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -276,7 +276,6 @@ void RemovableDriveManager::search_for_drives() search_path(path, pp); } - #endif } void RemovableDriveManager::search_path(const std::string &path,const std::string &parent_path) @@ -330,6 +329,7 @@ bool RemovableDriveManager::compare_filesystem_id(const std::string &path_a, con dev_t id_b = buf.st_dev; return id_a == id_b; } + void RemovableDriveManager::eject_drive(const std::string &path) { if (m_current_drives.empty()) @@ -518,3 +518,4 @@ void RemovableDriveManager::reset_last_save_path() m_last_save_path = ""; } }}//namespace Slicer::Gui + diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 1e5d240f09c..fa42f5e7357 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -6,7 +6,6 @@ namespace Slic3r { namespace GUI { -<<<<<<< HEAD #if __APPLE__ class RDMMMWrapper; #endif @@ -24,25 +23,12 @@ friend class RDMMMWrapper; #endif public: static RemovableDriveManager& get_instance() -======= -struct DriveData -{ - std::string name; - std::string path; - DriveData(std::string n, std::string p):name(n),path(p){} -}; -class RemovableDriveManager -{ -public: - static RemovableDriveManager& getInstance() ->>>>>>> removable drive manager - Windows part { static RemovableDriveManager instance; return instance; } RemovableDriveManager(RemovableDriveManager const&) = delete; void operator=(RemovableDriveManager const&) = delete; -<<<<<<< HEAD //call only once. on apple register for unmnount callbacks. on windows register for device notification is prepared but not called (eject usb drive on widnows doesnt trigger the callback, sdc ard does), also enumerates devices for first time so init shoud be called on linux too. void init(); //update() searches for removable devices, returns false if empty. /time = 0 is forced update, time expects wxGetLocalTime() @@ -107,25 +93,4 @@ protected: }; #endif }} -#endif -======= - - //update() searches for removable devices, returns false if empty. - static bool update(); - static bool is_drive_mounted(const std::string &path); - static void eject_drive(const std::string &path); - static std::string get_last_drive_path(); - static std::vector get_all_drives(); - static bool is_path_on_removable_drive(const std::string &path); -private: - RemovableDriveManager(){} - static void search_for_drives(); - static std::vector m_current_drives; -#if _WIN32 -#else - static void search_path(const std::string &path, const dev_t &parentDevID); -#endif -}; -}} -#endif ->>>>>>> removable drive manager - Windows part +#endif \ No newline at end of file From 0174c16c7f81f72161cac12d651ebeb28592b317 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 12 Dec 2019 15:43:14 +0100 Subject: [PATCH 105/123] button show after write --- src/slic3r/GUI/Plater.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 52255d17634..02f8ace078f 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3580,6 +3580,8 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt) //added to show disconnect_button after writing show_action_buttons(false); + show_action_buttons(false); + if (canceled) { if (wxGetApp().get_mode() == comSimple) sidebar->set_btn_label(ActionButtonType::abReslice, "Slice now"); From e01ab7dc60fc13d5ba27e4fa26f64991745cfbc9 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 13 Dec 2019 13:23:55 +0100 Subject: [PATCH 106/123] Implemented rescaling for "Remove device" button --- src/slic3r/GUI/Plater.cpp | 58 ++++++++++++++++++--------------- src/slic3r/GUI/wxExtensions.cpp | 8 +++-- src/slic3r/GUI/wxExtensions.hpp | 7 ++++ 3 files changed, 44 insertions(+), 29 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 02f8ace078f..cff3164e8e6 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -699,8 +699,8 @@ struct Sidebar::priv wxButton *btn_export_gcode; wxButton *btn_reslice; - wxButton *btn_send_gcode; - ScalableButton *btn_disconnect; + ScalableButton *btn_send_gcode; + ScalableButton *btn_remove_device; priv(Plater *plater) : plater(plater) {} ~priv(); @@ -849,25 +849,30 @@ Sidebar::Sidebar(Plater *parent) // Buttons underneath the scrolled area - auto init_btn = [this](wxButton **btn, wxString label, const std::string icon_name = "", wxString tooltip = wxEmptyString) { - *btn = new wxButton(this, wxID_ANY, label, wxDefaultPosition, - wxDefaultSize, wxBU_EXACTFIT); - (*btn)->SetFont(wxGetApp().bold_font()); - (*btn)->SetToolTip(tooltip); + // rescalable bitmap buttons "Send to printer" and "Remove device" - if (!icon_name.empty()) - (*btn)->SetBitmap(create_scaled_bitmap(this, icon_name)); + auto init_scalable_btn = [this](ScalableButton** btn, const std::string& icon_name, wxString tooltip = wxEmptyString) + { + ScalableBitmap bmp = ScalableBitmap(this, icon_name, int(2.5 * wxGetApp().em_unit())); + *btn = new ScalableButton(this, wxID_ANY, bmp, "", wxBU_EXACTFIT); + (*btn)->SetToolTip(tooltip); + (*btn)->Hide(); }; - init_btn(&p->btn_send_gcode, /*_(L("Send to printer"))*/"", "export_gcode", _(L("Send to printer"))); - p->btn_send_gcode->Hide(); - init_btn(&p->btn_export_gcode, _(L("Export G-code")) + dots); - init_btn(&p->btn_reslice, _(L("Slice now"))); + init_scalable_btn(&p->btn_send_gcode , "export_gcode", _(L("Send to printer"))); + init_scalable_btn(&p->btn_remove_device, "revert_all_" , _(L("Remove device"))); - p->btn_disconnect = new ScalableButton(this, wxID_ANY, "revert_all_", "", - wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT); - p->btn_disconnect->Hide(); - p->btn_disconnect->SetToolTip(_(L("Remove device"))); + // regular buttons "Slice now" and "Export G-code" + + const int scaled_height = p->btn_remove_device->GetBitmap().GetHeight() + 4; + auto init_btn = [this](wxButton **btn, wxString label, const int button_height) { + *btn = new wxButton(this, wxID_ANY, label, wxDefaultPosition, + wxSize(-1, button_height), wxBU_EXACTFIT); + (*btn)->SetFont(wxGetApp().bold_font()); + }; + + init_btn(&p->btn_export_gcode, _(L("Export G-code")) + dots , scaled_height); + init_btn(&p->btn_reslice , _(L("Slice now")) , scaled_height); enable_buttons(false); @@ -876,12 +881,10 @@ Sidebar::Sidebar(Plater *parent) auto* complect_btns_sizer = new wxBoxSizer(wxHORIZONTAL); complect_btns_sizer->Add(p->btn_export_gcode, 1, wxEXPAND); complect_btns_sizer->Add(p->btn_send_gcode, 0, wxEXPAND); - complect_btns_sizer->Add(p->btn_disconnect); + complect_btns_sizer->Add(p->btn_remove_device); btns_sizer->Add(p->btn_reslice, 0, wxEXPAND | wxTOP, margin_5); btns_sizer->Add(complect_btns_sizer, 0, wxEXPAND | wxTOP, margin_5); -// btns_sizer->Add(p->btn_send_gcode, 0, wxEXPAND | wxTOP, margin_5); -// btns_sizer->Add(p->btn_export_gcode, 0, wxEXPAND | wxTOP, margin_5); auto *sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(p->scrolled, 1, wxEXPAND); @@ -900,10 +903,7 @@ Sidebar::Sidebar(Plater *parent) p->plater->select_view_3D("Preview"); }); p->btn_send_gcode->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->send_gcode(); }); - p->btn_disconnect->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { - // #dk_FIXME - p->plater->eject_drive(); - }); + p->btn_remove_device->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->eject_drive(); }); } Sidebar::~Sidebar() {} @@ -1049,6 +1049,12 @@ void Sidebar::msw_rescale() p->object_info->msw_rescale(); + p->btn_send_gcode->msw_rescale(); + p->btn_remove_device->msw_rescale(); + const int scaled_height = p->btn_remove_device->GetBitmap().GetHeight() + 4; + p->btn_export_gcode->SetMinSize(wxSize(-1, scaled_height)); + p->btn_reslice ->SetMinSize(wxSize(-1, scaled_height)); + p->scrolled->Layout(); } @@ -1277,13 +1283,13 @@ void Sidebar::enable_buttons(bool enable) p->btn_reslice->Enable(enable); p->btn_export_gcode->Enable(enable); p->btn_send_gcode->Enable(enable); - p->btn_disconnect->Enable(enable); + p->btn_remove_device->Enable(enable); } bool Sidebar::show_reslice(bool show) const { return p->btn_reslice->Show(show); } bool Sidebar::show_export(bool show) const { return p->btn_export_gcode->Show(show); } bool Sidebar::show_send(bool show) const { return p->btn_send_gcode->Show(show); } -bool Sidebar::show_disconnect(bool show)const { return p->btn_disconnect->Show(show); } +bool Sidebar::show_disconnect(bool show)const { return p->btn_remove_device->Show(show); } bool Sidebar::is_multifilament() { diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 302a5e5210f..e64a3fce595 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -3935,8 +3935,10 @@ ScalableButton::ScalableButton( wxWindow * parent, const ScalableBitmap& bitmap, const wxString& label /*= wxEmptyString*/, long style /*= wxBU_EXACTFIT | wxNO_BORDER*/) : + m_parent(parent), m_current_icon_name(bitmap.name()), - m_parent(parent) + m_px_cnt(bitmap.px_cnt()), + m_is_horizontal(bitmap.is_horizontal()) { Create(parent, id, label, wxDefaultPosition, wxDefaultSize, style); #ifdef __WXMSW__ @@ -3961,9 +3963,9 @@ void ScalableButton::SetBitmapDisabled_(const ScalableBitmap& bmp) void ScalableButton::msw_rescale() { - SetBitmap(create_scaled_bitmap(m_parent, m_current_icon_name)); + SetBitmap(create_scaled_bitmap(m_parent, m_current_icon_name, m_px_cnt, m_is_horizontal)); if (!m_disabled_icon_name.empty()) - SetBitmapDisabled(create_scaled_bitmap(m_parent, m_disabled_icon_name)); + SetBitmapDisabled(create_scaled_bitmap(m_parent, m_disabled_icon_name, m_px_cnt, m_is_horizontal)); if (m_width > 0 || m_height>0) { diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 7841b62feea..951f7ea8f45 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -729,6 +729,9 @@ public: wxBitmap& bmp() { return m_bmp; } const std::string& name() const{ return m_icon_name; } + int px_cnt()const {return m_px_cnt;} + bool is_horizontal()const {return m_is_horizontal;} + private: wxWindow* m_parent{ nullptr }; wxBitmap m_bmp = wxBitmap(); @@ -1116,6 +1119,10 @@ private: std::string m_disabled_icon_name = ""; int m_width {-1}; // should be multiplied to em_unit int m_height{-1}; // should be multiplied to em_unit + + // bitmap dimensions + int m_px_cnt{ 16 }; + bool m_is_horizontal{ false }; }; From 7b32525ab0e6b8ddda1fba8194faf14bd9f41a41 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 13 Dec 2019 17:56:04 +0100 Subject: [PATCH 107/123] Fixed "actions" buttons size under OSX --- src/slic3r/GUI/Plater.cpp | 13 +++++++++---- src/slic3r/GUI/wxExtensions.cpp | 6 ++++++ src/slic3r/GUI/wxExtensions.hpp | 1 + 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 72d01b41d88..fa18bd5ea02 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -853,18 +853,23 @@ Sidebar::Sidebar(Plater *parent) auto init_scalable_btn = [this](ScalableButton** btn, const std::string& icon_name, wxString tooltip = wxEmptyString) { - ScalableBitmap bmp = ScalableBitmap(this, icon_name, int(2.5 * wxGetApp().em_unit())); +#ifdef __APPLE__ + int bmp_px_cnt = 16; +#else + int bmp_px_cnt = 32; +#endif //__APPLE__ + ScalableBitmap bmp = ScalableBitmap(this, icon_name, bmp_px_cnt); *btn = new ScalableButton(this, wxID_ANY, bmp, "", wxBU_EXACTFIT); (*btn)->SetToolTip(tooltip); (*btn)->Hide(); }; init_scalable_btn(&p->btn_send_gcode , "export_gcode", _(L("Send to printer"))); - init_scalable_btn(&p->btn_remove_device, "revert_all_" , _(L("Remove device"))); + init_scalable_btn(&p->btn_remove_device, "cross" , _(L("Remove device"))); // regular buttons "Slice now" and "Export G-code" - const int scaled_height = p->btn_remove_device->GetBitmap().GetHeight() + 4; + const int scaled_height = p->btn_remove_device->GetBitmapHeight() + 4; auto init_btn = [this](wxButton **btn, wxString label, const int button_height) { *btn = new wxButton(this, wxID_ANY, label, wxDefaultPosition, wxSize(-1, button_height), wxBU_EXACTFIT); @@ -880,7 +885,7 @@ Sidebar::Sidebar(Plater *parent) auto* complect_btns_sizer = new wxBoxSizer(wxHORIZONTAL); complect_btns_sizer->Add(p->btn_export_gcode, 1, wxEXPAND); - complect_btns_sizer->Add(p->btn_send_gcode, 0, wxEXPAND); + complect_btns_sizer->Add(p->btn_send_gcode); complect_btns_sizer->Add(p->btn_remove_device); btns_sizer->Add(p->btn_reslice, 0, wxEXPAND | wxTOP, margin_5); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index e64a3fce595..c359f76624a 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -3961,6 +3961,12 @@ void ScalableButton::SetBitmapDisabled_(const ScalableBitmap& bmp) m_disabled_icon_name = bmp.name(); } +int ScalableButton::GetBitmapHeight() +{ + const float scale_factor = get_svg_scale_factor(m_parent); + return int((float)GetBitmap().GetHeight() / scale_factor); +} + void ScalableButton::msw_rescale() { SetBitmap(create_scaled_bitmap(m_parent, m_current_icon_name, m_px_cnt, m_is_horizontal)); diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 951f7ea8f45..26e334def4a 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -1110,6 +1110,7 @@ public: void SetBitmap_(const ScalableBitmap& bmp); void SetBitmapDisabled_(const ScalableBitmap &bmp); + int GetBitmapHeight(); void msw_rescale(); From 8f32b9ca51bf2d38b0c9b42b95e6988ef315d55f Mon Sep 17 00:00:00 2001 From: David Kocik Date: Fri, 13 Dec 2019 18:02:25 +0100 Subject: [PATCH 108/123] message box about succesful removal --- src/slic3r/GUI/Plater.cpp | 11 ++++++-- src/slic3r/GUI/RemovableDriveManager.cpp | 34 ++++++++++++++++++++++-- src/slic3r/GUI/RemovableDriveManager.hpp | 6 +++++ 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 72d01b41d88..f1bdbb23ef3 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3583,8 +3583,7 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt) break; default: break; } - //added to show disconnect_button after writing - show_action_buttons(false); + if (canceled) { if (wxGetApp().get_mode() == comSimple) @@ -3593,6 +3592,11 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt) } else if (wxGetApp().get_mode() == comSimple) show_action_buttons(false); + else if(RemovableDriveManager::get_instance().get_is_writing()) + { + RemovableDriveManager::get_instance().set_is_writing(false); + show_action_buttons(false); + } } void Plater::priv::on_layer_editing_toggled(bool enable) @@ -4722,6 +4726,7 @@ void Plater::export_gcode() if (! output_path.empty()) { std::string path = output_path.string(); + RemovableDriveManager::get_instance().set_is_writing(true); p->export_gcode(std::move(output_path), PrintHostJob()); RemovableDriveManager::get_instance().update(0, true); RemovableDriveManager::get_instance().set_last_save_path(path); @@ -5016,6 +5021,8 @@ void Plater::eject_drive() } void Plater::drive_ejected_callback() { + wxString message = "Unmounting succesesful. The device " + RemovableDriveManager::get_instance().get_last_save_name() + "(" + RemovableDriveManager::get_instance().get_last_save_path() + ")" + " can now be safely removed from the computer."; + wxMessageBox(message); p->show_action_buttons(false); } diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 1c2a29b0ba0..535d62f83f6 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -43,7 +43,7 @@ void RemovableDriveManager::search_for_drives() if (drive_type == DRIVE_REMOVABLE) { // get name of drive - std::wstring wpath = std::wstring(path.begin(), path.end()); + std::wstring wpath = boost::nowide::widen(path);//std::wstring(path.begin(), path.end()); std::wstring volume_name; volume_name.resize(1024); std::wstring file_system_name; @@ -52,6 +52,7 @@ void RemovableDriveManager::search_for_drives() BOOL error = GetVolumeInformationW(wpath.c_str(), &volume_name[0], sizeof(volume_name), NULL, NULL, NULL, &file_system_name[0], sizeof(file_system_name)); if(error != 0) { + volume_name.erase(std::find(volume_name.begin(), volume_name.end(), '\0'), volume_name.end()); /* if (volume_name == L"") { @@ -398,7 +399,9 @@ std::string RemovableDriveManager::get_drive_from_path(const std::string& path) RemovableDriveManager::RemovableDriveManager(): m_drives_count(0), m_last_update(0), - m_last_save_path("") + m_last_save_path(""), + m_last_save_name(""), + m_is_writing(false) #if __APPLE__ , m_rdmmm(new RDMMMWrapper()) #endif @@ -459,6 +462,10 @@ std::string RemovableDriveManager::get_last_save_path() { return m_last_save_path; } +std::string RemovableDriveManager::get_last_save_name() +{ + return m_last_save_name; +} std::vector RemovableDriveManager::get_all_drives() { return m_current_drives; @@ -491,8 +498,22 @@ void RemovableDriveManager::set_last_save_path(const std::string& path) if(last_drive != "") { m_last_save_path = last_drive; + m_last_save_name = get_drive_name(last_drive); } } +std::string RemovableDriveManager::get_drive_name(const std::string& path) +{ + if (m_current_drives.size() == 0) + return ""; + for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) + { + if ((*it).path == path) + { + return (*it).name; + } + } + return ""; +} bool RemovableDriveManager::is_last_drive_removed() { //std::cout<<"is last: "< get_all_drives(); @@ -50,6 +51,9 @@ public: bool is_last_drive_removed(); // param as update() bool is_last_drive_removed_with_update(const long time = 0); + void set_is_writing(const bool b); + bool get_is_writing(); + std::string get_drive_name(const std::string& path); private: RemovableDriveManager(); void search_for_drives(); @@ -64,6 +68,8 @@ private: size_t m_drives_count; long m_last_update; std::string m_last_save_path; + std::string m_last_save_name; + bool m_is_writing;//on device #if _WIN32 //registers for notifications by creating invisible window From 9be525196b9d5fc08dcd0d05326ff31b29865703 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 16 Dec 2019 13:53:12 +0100 Subject: [PATCH 109/123] correct beahvior when disconnecting device other way than button in slicer --- src/slic3r/GUI/Plater.cpp | 21 +++++++++++++++------ src/slic3r/GUI/RemovableDriveManager.cpp | 23 +++++++++++++++++++---- src/slic3r/GUI/RemovableDriveManager.hpp | 3 +++ 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index ce29120abc4..63521815df2 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3600,6 +3600,8 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt) else if(RemovableDriveManager::get_instance().get_is_writing()) { RemovableDriveManager::get_instance().set_is_writing(false); + //RemovableDriveManager::get_instance().erase_callbacks(); + //RemovableDriveManager::get_instance().add_callback(std::bind(&Plater::drive_ejected_callback, q)); show_action_buttons(false); } } @@ -4168,8 +4170,7 @@ void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const const auto prin_host_opt = config->option("print_host"); const bool send_gcode_shown = prin_host_opt != nullptr && !prin_host_opt->value.empty(); - const bool disconnect_shown = !(RemovableDriveManager::get_instance().is_last_drive_removed()); // #dk_FIXME - + bool disconnect_shown = !RemovableDriveManager::get_instance().is_last_drive_removed() ; // #dk_FIXME // when a background processing is ON, export_btn and/or send_btn are showing if (wxGetApp().app_config->get("background_processing") == "1") { @@ -4735,6 +4736,11 @@ void Plater::export_gcode() p->export_gcode(std::move(output_path), PrintHostJob()); RemovableDriveManager::get_instance().update(0, true); RemovableDriveManager::get_instance().set_last_save_path(path); + if(!RemovableDriveManager::get_instance().is_last_drive_removed()) + { + RemovableDriveManager::get_instance().erase_callbacks(); + RemovableDriveManager::get_instance().add_callback(std::bind(&Plater::drive_ejected_callback, this)); + } } } @@ -5019,15 +5025,18 @@ void Plater::send_gcode() void Plater::eject_drive() { RemovableDriveManager::get_instance().update(0, true); - RemovableDriveManager::get_instance().erase_callbacks(); - RemovableDriveManager::get_instance().add_callback(std::bind(&Plater::drive_ejected_callback, this)); + //RemovableDriveManager::get_instance().erase_callbacks(); + //RemovableDriveManager::get_instance().add_callback(std::bind(&Plater::drive_ejected_callback, this)); RemovableDriveManager::get_instance().eject_drive(RemovableDriveManager::get_instance().get_last_save_path()); } void Plater::drive_ejected_callback() { - wxString message = "Unmounting succesesful. The device " + RemovableDriveManager::get_instance().get_last_save_name() + "(" + RemovableDriveManager::get_instance().get_last_save_path() + ")" + " can now be safely removed from the computer."; - wxMessageBox(message); + if (RemovableDriveManager::get_instance().get_did_eject()) + { + wxString message = "Unmounting succesesful. The device " + RemovableDriveManager::get_instance().get_last_save_name() + "(" + RemovableDriveManager::get_instance().get_last_save_path() + ")" + " can now be safely removed from the computer."; + wxMessageBox(message); + } p->show_action_buttons(false); } diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 535d62f83f6..5af4362f270 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -106,7 +106,7 @@ void RemovableDriveManager::eject_drive(const std::string &path) return; } CloseHandle(handle); - + m_did_eject = true; m_current_drives.erase(it); break; } @@ -365,6 +365,7 @@ void RemovableDriveManager::eject_drive(const std::string &path) std::cerr<<"Ejecting failed\n"; return; } + m_did_eject = true; m_current_drives.erase(it); break; @@ -401,12 +402,18 @@ RemovableDriveManager::RemovableDriveManager(): m_last_update(0), m_last_save_path(""), m_last_save_name(""), - m_is_writing(false) + m_is_writing(false), + m_did_eject(false) #if __APPLE__ , m_rdmmm(new RDMMMWrapper()) #endif {} - +RemovableDriveManager::~RemovableDriveManager() +{ +#if __APPLE__ + delete m_rdmmm; +#endif +} void RemovableDriveManager::init() { //add_callback([](void) { RemovableDriveManager::get_instance().print(); }); @@ -517,7 +524,7 @@ std::string RemovableDriveManager::get_drive_name(const std::string& path) bool RemovableDriveManager::is_last_drive_removed() { //std::cout<<"is last: "< Date: Mon, 16 Dec 2019 14:06:25 +0100 Subject: [PATCH 110/123] macos first update bug fix --- src/slic3r/GUI/RemovableDriveManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 5af4362f270..f8d7883f55f 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -422,7 +422,7 @@ void RemovableDriveManager::init() #elif __APPLE__ m_rdmmm->register_window(); #endif - update(); + update(0, true); } bool RemovableDriveManager::update(const long time,const bool check) { From 97b4c9c692dbad989db8a3fd1fb9e72d8bfde2a0 Mon Sep 17 00:00:00 2001 From: Slic3rPE Date: Mon, 16 Dec 2019 15:46:25 +0100 Subject: [PATCH 111/123] macos detecting also mounting of dev --- src/slic3r/GUI/RemovableDriveManagerMM.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.mm b/src/slic3r/GUI/RemovableDriveManagerMM.mm index 45bd21bcfaa..3bb017a3aa2 100644 --- a/src/slic3r/GUI/RemovableDriveManagerMM.mm +++ b/src/slic3r/GUI/RemovableDriveManagerMM.mm @@ -23,6 +23,7 @@ { NSLog(@"add unmount observer"); [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(on_device_unmount:) name:NSWorkspaceDidUnmountNotification object:nil]; + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(on_device_unmount:) name:NSWorkspaceDidMountNotification object:nil]; } -(NSArray*) list_dev { From 6b747eb88f84be27fb462f7b8c00f27c88a8d1ea Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 16 Dec 2019 15:47:36 +0100 Subject: [PATCH 112/123] save last path earlier --- src/slic3r/GUI/Plater.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 63521815df2..7cd4f195ba7 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4733,9 +4733,9 @@ void Plater::export_gcode() { std::string path = output_path.string(); RemovableDriveManager::get_instance().set_is_writing(true); - p->export_gcode(std::move(output_path), PrintHostJob()); RemovableDriveManager::get_instance().update(0, true); RemovableDriveManager::get_instance().set_last_save_path(path); + p->export_gcode(std::move(output_path), PrintHostJob()); if(!RemovableDriveManager::get_instance().is_last_drive_removed()) { RemovableDriveManager::get_instance().erase_callbacks(); From 0ed4b6bfe1cff01845ef94a2369a3741f98cdbc5 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 16 Dec 2019 17:15:27 +0100 Subject: [PATCH 113/123] verification of save path --- src/slic3r/GUI/Plater.cpp | 18 +++++++++++++----- src/slic3r/GUI/RemovableDriveManager.cpp | 20 ++++++++++++++------ src/slic3r/GUI/RemovableDriveManager.hpp | 3 ++- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 7cd4f195ba7..29b83bebabb 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3597,12 +3597,18 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt) } else if (wxGetApp().get_mode() == comSimple) show_action_buttons(false); - else if(RemovableDriveManager::get_instance().get_is_writing()) + if(RemovableDriveManager::get_instance().get_is_writing()) { RemovableDriveManager::get_instance().set_is_writing(false); - //RemovableDriveManager::get_instance().erase_callbacks(); - //RemovableDriveManager::get_instance().add_callback(std::bind(&Plater::drive_ejected_callback, q)); - show_action_buttons(false); + RemovableDriveManager::get_instance().verify_last_save_path(); + if (!RemovableDriveManager::get_instance().is_last_drive_removed()) + { + + RemovableDriveManager::get_instance().erase_callbacks(); + RemovableDriveManager::get_instance().add_callback(std::bind(&Plater::drive_ejected_callback, q)); + show_action_buttons(false); + } + } } @@ -4734,13 +4740,15 @@ void Plater::export_gcode() std::string path = output_path.string(); RemovableDriveManager::get_instance().set_is_writing(true); RemovableDriveManager::get_instance().update(0, true); - RemovableDriveManager::get_instance().set_last_save_path(path); p->export_gcode(std::move(output_path), PrintHostJob()); + RemovableDriveManager::get_instance().set_last_save_path(path); + /* if(!RemovableDriveManager::get_instance().is_last_drive_removed()) { RemovableDriveManager::get_instance().erase_callbacks(); RemovableDriveManager::get_instance().add_callback(std::bind(&Plater::drive_ejected_callback, this)); } + */ } } diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index f8d7883f55f..52a8c2b77e3 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -402,6 +402,7 @@ RemovableDriveManager::RemovableDriveManager(): m_last_update(0), m_last_save_path(""), m_last_save_name(""), + m_last_save_path_verified(false), m_is_writing(false), m_did_eject(false) #if __APPLE__ @@ -442,7 +443,6 @@ bool RemovableDriveManager::update(const long time,const bool check) return !m_current_drives.empty(); } - bool RemovableDriveManager::is_drive_mounted(const std::string &path) { for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) @@ -461,12 +461,14 @@ std::string RemovableDriveManager::get_drive_path() reset_last_save_path(); return ""; } - if (m_last_save_path != "") + if (m_last_save_path_verified) return m_last_save_path; return m_current_drives.back().path; } std::string RemovableDriveManager::get_last_save_path() { + if (!m_last_save_path_verified) + return ""; return m_last_save_path; } std::string RemovableDriveManager::get_last_save_name() @@ -481,7 +483,7 @@ void RemovableDriveManager::check_and_notify() { if(m_drives_count != m_current_drives.size()) { - if(m_callbacks.size() != 0 && m_drives_count > m_current_drives.size() && m_last_save_path != "" && !is_drive_mounted(m_last_save_path)) + if(m_callbacks.size() != 0 && m_drives_count > m_current_drives.size() && m_last_save_path_verified && !is_drive_mounted(m_last_save_path)) { for (auto it = m_callbacks.begin(); it != m_callbacks.end(); ++it) { @@ -501,9 +503,14 @@ void RemovableDriveManager::erase_callbacks() } void RemovableDriveManager::set_last_save_path(const std::string& path) { - std::string last_drive = get_drive_from_path(path); - if(last_drive != "") + m_last_save_path = path; +} +void RemovableDriveManager::verify_last_save_path() +{ + std::string last_drive = get_drive_from_path(m_last_save_path); + if (last_drive != "") { + m_last_save_path_verified = true; m_last_save_path = last_drive; m_last_save_name = get_drive_name(last_drive); } @@ -525,7 +532,7 @@ bool RemovableDriveManager::is_last_drive_removed() { //std::cout<<"is last: "< Date: Tue, 17 Dec 2019 13:08:17 +0100 Subject: [PATCH 114/123] macos device detection --- src/slic3r/CMakeLists.txt | 8 +++ src/slic3r/GUI/RemovableDriveManager.cpp | 2 + src/slic3r/GUI/RemovableDriveManager.hpp | 1 + src/slic3r/GUI/RemovableDriveManagerMM.h | 1 + src/slic3r/GUI/RemovableDriveManagerMM.mm | 86 ++++++++++++++++++++++- 5 files changed, 96 insertions(+), 2 deletions(-) diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index a06a8cf1d14..5b55b96b4bc 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -172,6 +172,9 @@ if (APPLE) GUI/RemovableDriveManagerMM.mm GUI/RemovableDriveManagerMM.h ) + #DK + FIND_LIBRARY(DISKARBITRATION_LIBRARY DiskArbitration) + endif () add_library(libslic3r_gui STATIC ${SLIC3R_GUI_SOURCES}) @@ -179,6 +182,11 @@ add_library(libslic3r_gui STATIC ${SLIC3R_GUI_SOURCES}) encoding_check(libslic3r_gui) target_link_libraries(libslic3r_gui libslic3r avrdude cereal imgui GLEW::GLEW OpenGL::GL OpenGL::GLU hidapi) +#DK +if(APPLE) + target_link_libraries(libslic3r_gui ${DISKARBITRATION_LIBRARY}) +endif() + if (SLIC3R_PCH AND NOT SLIC3R_SYNTAXONLY) add_precompiled_header(libslic3r_gui pchheader.hpp FORCEINCLUDE) endif () diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 52a8c2b77e3..6e13a59b5ce 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -354,6 +354,7 @@ void RemovableDriveManager::eject_drive(const std::string &path) // but neither triggers "succesful safe removal messege" std::string command = ""; #if __APPLE__ + //m_rdmmm->eject_device(path); command = "diskutil unmount "; #else command = "umount "; @@ -365,6 +366,7 @@ void RemovableDriveManager::eject_drive(const std::string &path) std::cerr<<"Ejecting failed\n"; return; } + m_did_eject = true; m_current_drives.erase(it); diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 2e9fc9f4ef4..1b337338e98 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -96,6 +96,7 @@ public: ~RDMMMWrapper(); void register_window(); void list_devices(); + void eject_device(const std::string &path); void log(const std::string &msg); protected: void *m_imp; diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.h b/src/slic3r/GUI/RemovableDriveManagerMM.h index 29994154546..71239dba32c 100644 --- a/src/slic3r/GUI/RemovableDriveManagerMM.h +++ b/src/slic3r/GUI/RemovableDriveManagerMM.h @@ -6,4 +6,5 @@ -(void) add_unmount_observer; -(void) on_device_unmount: (NSNotification*) notification; -(NSArray*) list_dev; +-(void)eject_drive:(NSString *)path; @end diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.mm b/src/slic3r/GUI/RemovableDriveManagerMM.mm index 3bb017a3aa2..01d38b1855d 100644 --- a/src/slic3r/GUI/RemovableDriveManagerMM.mm +++ b/src/slic3r/GUI/RemovableDriveManagerMM.mm @@ -1,6 +1,7 @@ #import "RemovableDriveManager.hpp" #import "RemovableDriveManagerMM.h" #import +#import @implementation RemovableDriveManagerMM @@ -27,9 +28,81 @@ } -(NSArray*) list_dev { - NSArray* devices = [[NSWorkspace sharedWorkspace] mountedRemovableMedia]; - return devices; + // DEPRICATED: + //NSArray* devices = [[NSWorkspace sharedWorkspace] mountedRemovableMedia]; + //return devices; + NSArray *mountedRemovableMedia = [[NSFileManager defaultManager] mountedVolumeURLsIncludingResourceValuesForKeys:nil options:NSVolumeEnumerationSkipHiddenVolumes]; + NSMutableArray *result = [NSMutableArray array]; + for(NSURL *volURL in mountedRemovableMedia) + { + int err = 0; + DADiskRef disk; + DASessionRef session; + CFDictionaryRef descDict; + session = DASessionCreate(NULL); + if (session == NULL) { + err = EINVAL; + } + if (err == 0) { + disk = DADiskCreateFromVolumePath(NULL,session,(CFURLRef)volURL); + if (session == NULL) { + err = EINVAL; + } + } + if (err == 0) { + descDict = DADiskCopyDescription(disk); + if (descDict == NULL) { + err = EINVAL; + } + } + if (err == 0) { + CFTypeRef mediaEjectableKey = CFDictionaryGetValue(descDict,kDADiskDescriptionMediaEjectableKey); + BOOL ejectable = [mediaEjectableKey boolValue]; + CFTypeRef deviceProtocolName = CFDictionaryGetValue(descDict,kDADiskDescriptionDeviceProtocolKey); + CFTypeRef deviceModelKey = CFDictionaryGetValue(descDict, kDADiskDescriptionDeviceModelKey); + if (mediaEjectableKey != NULL) + { + BOOL op = ejectable && (CFEqual(deviceProtocolName, CFSTR("USB")) || CFEqual(deviceModelKey, CFSTR("SD Card Reader"))); + //!CFEqual(deviceModelKey, CFSTR("Disk Image")); + // + if (op) { + [result addObject:volURL.path]; + } + } + } + if (descDict != NULL) { + CFRelease(descDict); + } + + + } + return result; +} +-(void)eject_drive:(NSString *)path +{ + DADiskRef disk; + DASessionRef session; + NSURL *url = [[NSURL alloc] initFileURLWithPath:path]; + int err = 0; + session = DASessionCreate(NULL); + if (session == NULL) { + err = EINVAL; + } + if (err == 0) { + disk = DADiskCreateFromVolumePath(NULL,session,(CFURLRef)url); + } + if( err == 0) + { + DADiskUnmount(disk, kDADiskUnmountOptionDefault, + NULL, NULL); + } + if (disk != NULL) { + CFRelease(disk); + } + if (session != NULL) { + CFRelease(session); + } } namespace Slic3r { namespace GUI { @@ -66,6 +139,15 @@ void RDMMMWrapper::log(const std::string &msg) { NSLog(@"%s", msg.c_str()); } +void RDMMMWrapper::eject_device(const std::string &path) +{ + if(m_imp) + { + NSString * pth = [NSString stringWithCString:path.c_str() + encoding:[NSString defaultCStringEncoding]]; + [m_imp eject_drive:pth]; + } +} }}//namespace Slicer::GUI /* From 025e675533936ebb63c969ff73c543e73afa53a8 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 17 Dec 2019 16:50:00 +0100 Subject: [PATCH 115/123] Fix linking of OpenVDB in debug mode on multi conf generators. --- cmake/modules/FindOpenVDB.cmake | 50 +++++++++++++++++++++++++++------ deps/CMakeLists.txt | 1 + 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/cmake/modules/FindOpenVDB.cmake b/cmake/modules/FindOpenVDB.cmake index 9afe8a23567..8c91fac05a6 100644 --- a/cmake/modules/FindOpenVDB.cmake +++ b/cmake/modules/FindOpenVDB.cmake @@ -203,20 +203,44 @@ if(UNIX AND OPENVDB_USE_STATIC_LIBS) endif() set(OpenVDB_LIB_COMPONENTS "") +set(OpenVDB_DEBUG_SUFFIX "d" CACHE STRING "Suffix for the debug libraries") + +get_property(_is_multi GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) set(LIB_NAME ${COMPONENT}) - find_library(OpenVDB_${COMPONENT}_LIBRARY ${LIB_NAME} lib${LIB_NAME} + + find_library(OpenVDB_${COMPONENT}_LIBRARY_RELEASE ${LIB_NAME} lib${LIB_NAME} PATHS ${_OPENVDB_LIBRARYDIR_SEARCH_DIRS} PATH_SUFFIXES ${OPENVDB_PATH_SUFFIXES} ) - list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY}) - if(OpenVDB_${COMPONENT}_LIBRARY) - set(OpenVDB_${COMPONENT}_FOUND TRUE) - else() - set(OpenVDB_${COMPONENT}_FOUND FALSE) - endif() + find_library(OpenVDB_${COMPONENT}_LIBRARY_DEBUG ${LIB_NAME}${OpenVDB_DEBUG_SUFFIX} lib${LIB_NAME}${OpenVDB_DEBUG_SUFFIX} + PATHS ${_OPENVDB_LIBRARYDIR_SEARCH_DIRS} + PATH_SUFFIXES ${OPENVDB_PATH_SUFFIXES} + ) + + if (_is_multi) + list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY_RELEASE} ${OpenVDB_${COMPONENT}_LIBRARY_DEBUG}) + + if(OpenVDB_${COMPONENT}_LIBRARY_RELEASE AND ${OpenVDB_${COMPONENT}_LIBRARY_DEBUG}) + set(OpenVDB_${COMPONENT}_FOUND TRUE) + else() + set(OpenVDB_${COMPONENT}_FOUND FALSE) + endif() + else () + string(TOUPPER "${CMAKE_BUILD_TYPE}" _BUILD_TYPE) + + set(OpenVDB_${COMPONENT}_LIBRARY ${OpenVDB_${COMPONENT}_LIBRARY_${_BUILD_TYPE}}) + + list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY}) + + if(OpenVDB_${COMPONENT}_LIBRARY) + set(OpenVDB_${COMPONENT}_FOUND TRUE) + else() + set(OpenVDB_${COMPONENT}_FOUND FALSE) + endif() + endif () endforeach() if(UNIX AND OPENVDB_USE_STATIC_LIBS) @@ -465,7 +489,6 @@ foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) if(NOT TARGET OpenVDB::${COMPONENT}) add_library(OpenVDB::${COMPONENT} UNKNOWN IMPORTED) set_target_properties(OpenVDB::${COMPONENT} PROPERTIES - IMPORTED_LOCATION "${OpenVDB_${COMPONENT}_LIBRARY}" INTERFACE_COMPILE_OPTIONS "${OpenVDB_DEFINITIONS}" INTERFACE_INCLUDE_DIRECTORIES "${OpenVDB_INCLUDE_DIR}" IMPORTED_LINK_DEPENDENT_LIBRARIES "${_OPENVDB_HIDDEN_DEPENDENCIES}" # non visible deps @@ -473,6 +496,17 @@ foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) INTERFACE_COMPILE_FEATURES cxx_std_11 ) + if (_is_multi) + set_target_properties(OpenVDB::${COMPONENT} PROPERTIES + IMPORTED_LOCATION_RELEASE "${OpenVDB_${COMPONENT}_LIBRARY_RELEASE}" + IMPORTED_LOCATION_DEBUG "${OpenVDB_${COMPONENT}_LIBRARY_DEBUG}" + ) + else () + set_target_properties(OpenVDB::${COMPONENT} PROPERTIES + IMPORTED_LOCATION "${OpenVDB_${COMPONENT}_LIBRARY}" + ) + endif () + if (OPENVDB_USE_STATIC_LIBS) set_target_properties(OpenVDB::${COMPONENT} PROPERTIES INTERFACE_COMPILE_DEFINITIONS "OPENVDB_STATICLIB;OPENVDB_OPENEXR_STATICLIB" diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index aeb078172cd..3935e38c3d7 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -47,6 +47,7 @@ message(STATUS "PrusaSlicer deps debug build: ${DEP_DEBUG}") find_package(Git REQUIRED) +get_property(_is_multi GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) function(prusaslicer_add_cmake_project projectname) cmake_parse_arguments(P_ARGS "" "INSTALL_DIR;BUILD_COMMAND;INSTALL_COMMAND" "CMAKE_ARGS" ${ARGN}) From 7e6aa437b04aa3b5d7c1ad4ebc756545290c6633 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 17 Dec 2019 16:56:11 +0100 Subject: [PATCH 116/123] Only consider openvdb debug if necessary. --- cmake/modules/FindOpenVDB.cmake | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmake/modules/FindOpenVDB.cmake b/cmake/modules/FindOpenVDB.cmake index 8c91fac05a6..8d8c1089b14 100644 --- a/cmake/modules/FindOpenVDB.cmake +++ b/cmake/modules/FindOpenVDB.cmake @@ -223,7 +223,9 @@ foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) if (_is_multi) list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY_RELEASE} ${OpenVDB_${COMPONENT}_LIBRARY_DEBUG}) - if(OpenVDB_${COMPONENT}_LIBRARY_RELEASE AND ${OpenVDB_${COMPONENT}_LIBRARY_DEBUG}) + list(FIND CMAKE_CONFIGURATION_TYPES "Debug" _has_debug) + + if(OpenVDB_${COMPONENT}_LIBRARY_RELEASE AND (_has_debug LESS 0 OR OpenVDB_${COMPONENT}_LIBRARY_DEBUG)) set(OpenVDB_${COMPONENT}_FOUND TRUE) else() set(OpenVDB_${COMPONENT}_FOUND FALSE) From f680376dd5e45c38eff8ea030f8a7c57cab11a99 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 17 Dec 2019 17:08:43 +0100 Subject: [PATCH 117/123] Grab the release in debug mode if there is no debug when not on msvc --- cmake/modules/FindOpenVDB.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmake/modules/FindOpenVDB.cmake b/cmake/modules/FindOpenVDB.cmake index 8d8c1089b14..b75bc6ed01a 100644 --- a/cmake/modules/FindOpenVDB.cmake +++ b/cmake/modules/FindOpenVDB.cmake @@ -235,6 +235,10 @@ foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) set(OpenVDB_${COMPONENT}_LIBRARY ${OpenVDB_${COMPONENT}_LIBRARY_${_BUILD_TYPE}}) + if (NOT MSVC AND NOT OpenVDB_${COMPONENT}_LIBRARY) + set(OpenVDB_${COMPONENT}_LIBRARY ${OpenVDB_${COMPONENT}_LIBRARY_RELEASE}) + endif () + list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY}) if(OpenVDB_${COMPONENT}_LIBRARY) From 3d7aa3e5038ca465ca3738bff4013f2c635ae637 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 18 Dec 2019 09:06:21 +0100 Subject: [PATCH 118/123] Show context menu for a multi-object selection on 3DScene, add "Reload from disk" item for this menu --- src/slic3r/GUI/GUI_ObjectList.cpp | 11 ++++++++--- src/slic3r/GUI/GUI_ObjectList.hpp | 4 ++-- src/slic3r/GUI/Plater.cpp | 3 +++ 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index c0520cb9a95..a058de80552 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -3874,8 +3874,8 @@ void ObjectList::show_multi_selection_menu() GetSelections(sels); for (const wxDataViewItem& item : sels) - if (!(m_objects_model->GetItemType(item) & (itVolume | itObject))) - // show this menu only for Object(s)/Volume(s) selection + if (!(m_objects_model->GetItemType(item) & (itVolume | itObject | itInstance))) + // show this menu only for Objects(Instances mixed with Objects)/Volumes selection return; wxMenu* menu = new wxMenu(); @@ -3885,7 +3885,12 @@ void ObjectList::show_multi_selection_menu() _(L("Select extruder number for selected objects and/or parts")), [this](wxCommandEvent&) { extruder_selection(); }, "", menu); - PopupMenu(menu); + append_menu_item(menu, wxID_ANY, _(L("Reload from disk")), _(L("Reload the selected volumes from disk")), + [this](wxCommandEvent&) { wxGetApp().plater()->reload_from_disk(); }, "", menu, []() { + return wxGetApp().plater()->can_reload_from_disk(); + }, wxGetApp().plater()); + + wxGetApp().plater()->PopupMenu(menu); } void ObjectList::extruder_selection() diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 73b23453b81..a5a72ad8c5a 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -366,6 +366,8 @@ public: void update_printable_state(int obj_idx, int instance_idx); void toggle_printable_state(wxDataViewItem item); + void show_multi_selection_menu(); + private: #ifdef __WXOSX__ // void OnChar(wxKeyEvent& event); @@ -384,8 +386,6 @@ private: void OnEditingStarted(wxDataViewEvent &event); #endif /* __WXMSW__ */ void OnEditingDone(wxDataViewEvent &event); - - void show_multi_selection_menu(); void extruder_selection(); void set_extruder_for_selected_items(const int extruder) const ; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index ef891b3b33e..107d55de01d 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3615,7 +3615,10 @@ void Plater::priv::on_right_click(RBtnEvent& evt) if (evt.data.second) // right button was clicked on empty space menu = &default_menu; else + { + sidebar->obj_list()->show_multi_selection_menu(); return; + } } else { From 638b66e3577c2c6f59bf2d94019f6a7c5c3135b7 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 18 Dec 2019 09:36:26 +0100 Subject: [PATCH 119/123] bug fix - using two devices --- src/slic3r/GUI/RemovableDriveManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 6e13a59b5ce..d10447cc66e 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -505,6 +505,7 @@ void RemovableDriveManager::erase_callbacks() } void RemovableDriveManager::set_last_save_path(const std::string& path) { + m_last_save_path_verified = false; m_last_save_path = path; } void RemovableDriveManager::verify_last_save_path() From 05b20d84ef8f44a74155f05a4890d2fccf09e0a4 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 18 Dec 2019 09:56:38 +0100 Subject: [PATCH 120/123] set_did_eject method --- src/slic3r/GUI/Plater.cpp | 1 + src/slic3r/GUI/RemovableDriveManager.cpp | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 523cd2bd316..79ebd28505d 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -5050,6 +5050,7 @@ void Plater::drive_ejected_callback() { if (RemovableDriveManager::get_instance().get_did_eject()) { + RemovableDriveManager::get_instance().set_did_eject(false); wxString message = "Unmounting succesesful. The device " + RemovableDriveManager::get_instance().get_last_save_name() + "(" + RemovableDriveManager::get_instance().get_last_save_path() + ")" + " can now be safely removed from the computer."; wxMessageBox(message); } diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index d10447cc66e..7a2464351c9 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -572,4 +572,8 @@ bool RemovableDriveManager::get_did_eject() { return m_did_eject; } +void RemovableDriveManager::set_did_eject(const bool b) +{ + m_did_eject = b; +} }}//namespace Slicer::Gui From a5314501e1c05bcd2d8199a16f0ab06d6f0438f7 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 18 Dec 2019 10:08:17 +0100 Subject: [PATCH 121/123] set_did_eject method --- src/slic3r/GUI/Plater.cpp | 1 + src/slic3r/GUI/RemovableDriveManager.cpp | 4 ++++ src/slic3r/GUI/RemovableDriveManager.hpp | 1 + 3 files changed, 6 insertions(+) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 523cd2bd316..79ebd28505d 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -5050,6 +5050,7 @@ void Plater::drive_ejected_callback() { if (RemovableDriveManager::get_instance().get_did_eject()) { + RemovableDriveManager::get_instance().set_did_eject(false); wxString message = "Unmounting succesesful. The device " + RemovableDriveManager::get_instance().get_last_save_name() + "(" + RemovableDriveManager::get_instance().get_last_save_path() + ")" + " can now be safely removed from the computer."; wxMessageBox(message); } diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index d10447cc66e..7a2464351c9 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -572,4 +572,8 @@ bool RemovableDriveManager::get_did_eject() { return m_did_eject; } +void RemovableDriveManager::set_did_eject(const bool b) +{ + m_did_eject = b; +} }}//namespace Slicer::Gui diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 1b337338e98..ea4584feee4 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -56,6 +56,7 @@ public: void set_is_writing(const bool b); bool get_is_writing(); bool get_did_eject(); + void set_did_eject(const bool b); std::string get_drive_name(const std::string& path); private: RemovableDriveManager(); From a089bb4e7b075c583cdada47f5a12722209b25c9 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 18 Dec 2019 10:17:47 +0100 Subject: [PATCH 122/123] Trying to fix a compilation issue on Linux / OSX --- src/slic3r/GUI/wxExtensions.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 9b7de93cdb0..0c43be3a086 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -962,7 +962,7 @@ private: bool operator<(const TICK_CODE& other) const { return other.tick > this->tick; } bool operator>(const TICK_CODE& other) const { return other.tick < this->tick; } - int tick; + int tick = 0; std::string gcode = Slic3r::ColorChangeCode; int extruder = 0; std::string color; From 81a0eba2b68ae634bf0192273dcd7eabfff677c1 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 18 Dec 2019 10:34:26 +0100 Subject: [PATCH 123/123] removableDriveManager bug fixes --- deps/CGAL/CGAL.cmake | 6 + deps/GMP/GMP.cmake | 2 +- resources/icons/thumb_down.svg | 2 +- resources/icons/thumb_up.svg | 2 +- src/hidapi/CMakeLists.txt | 2 +- src/hidapi/README.md | 5 + src/libslic3r/Format/3mf.cpp | 45 ++-- src/libslic3r/Format/AMF.cpp | 14 +- src/libslic3r/GCode.cpp | 40 ++-- src/libslic3r/GCode.hpp | 2 +- src/libslic3r/GCodeWriter.hpp | 5 + src/libslic3r/Model.cpp | 53 ++++- src/libslic3r/Model.hpp | 31 +-- src/libslic3r/Print.cpp | 4 +- src/libslic3r/PrintConfig.hpp | 6 - src/libslic3r/ShortestPath.cpp | 11 +- src/libslic3r/Slicing.cpp | 98 +++----- src/libslic3r/Slicing.hpp | 14 +- src/libslic3r/SlicingAdaptive.cpp | 246 ++++++++++++-------- src/libslic3r/SlicingAdaptive.hpp | 48 ++-- src/libslic3r/Technologies.hpp | 3 + src/slic3r/GUI/BackgroundSlicingProcess.cpp | 7 +- src/slic3r/GUI/GLCanvas3D.cpp | 72 +++--- src/slic3r/GUI/GLCanvas3D.hpp | 8 +- src/slic3r/GUI/GUI_Preview.cpp | 10 +- src/slic3r/GUI/ImGuiWrapper.cpp | 10 + src/slic3r/GUI/ImGuiWrapper.hpp | 2 + src/slic3r/GUI/Mouse3DController.cpp | 219 +++++++++++------ src/slic3r/GUI/Mouse3DController.hpp | 19 +- src/slic3r/GUI/Plater.cpp | 28 ++- src/slic3r/GUI/PresetBundle.cpp | 4 + src/slic3r/GUI/RemovableDriveManager.cpp | 5 + src/slic3r/GUI/RemovableDriveManager.hpp | 1 + src/slic3r/GUI/wxExtensions.cpp | 42 ++-- src/slic3r/GUI/wxExtensions.hpp | 17 +- version.inc | 6 +- 36 files changed, 620 insertions(+), 469 deletions(-) create mode 100644 src/hidapi/README.md diff --git a/deps/CGAL/CGAL.cmake b/deps/CGAL/CGAL.cmake index 4b127cd5125..96a62925802 100644 --- a/deps/CGAL/CGAL.cmake +++ b/deps/CGAL/CGAL.cmake @@ -6,4 +6,10 @@ prusaslicer_add_cmake_project( # URL https://github.com/CGAL/cgal/archive/releases/CGAL-5.0.zip # URL_HASH SHA256=bd9327be903ab7ee379a8a7a0609eba0962f5078d2497cf8e13e8e1598584154 DEPENDS dep_boost dep_GMP dep_MPFR +) + +ExternalProject_Add_Step(dep_CGAL dep_CGAL_relocation_fix + DEPENDEES install + COMMAND ${CMAKE_COMMAND} -E remove CGALConfig-installation-dirs.cmake + WORKING_DIRECTORY "${DESTDIR}/usr/local/lib/cmake/CGAL" ) \ No newline at end of file diff --git a/deps/GMP/GMP.cmake b/deps/GMP/GMP.cmake index 6c93107c42d..8bcf9485928 100644 --- a/deps/GMP/GMP.cmake +++ b/deps/GMP/GMP.cmake @@ -20,7 +20,7 @@ else () ExternalProject_Add(dep_GMP URL https://gmplib.org/download/gmp/gmp-6.1.2.tar.bz2 BUILD_IN_SOURCE ON - CONFIGURE_COMMAND ./configure --enable-shared=no --enable-static=yes "--prefix=${DESTDIR}/usr/local" --with-pic + CONFIGURE_COMMAND ./configure --enable-shared=no --enable-cxx=yes --enable-static=yes "--prefix=${DESTDIR}/usr/local" --with-pic BUILD_COMMAND make -j INSTALL_COMMAND make install ) diff --git a/resources/icons/thumb_down.svg b/resources/icons/thumb_down.svg index 0499cea4192..f789b731744 100644 --- a/resources/icons/thumb_down.svg +++ b/resources/icons/thumb_down.svg @@ -4,7 +4,7 @@ viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve"> - + diff --git a/resources/icons/thumb_up.svg b/resources/icons/thumb_up.svg index c9045929bed..1a0c6f1b7f1 100644 --- a/resources/icons/thumb_up.svg +++ b/resources/icons/thumb_up.svg @@ -4,7 +4,7 @@ viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve"> - + diff --git a/src/hidapi/CMakeLists.txt b/src/hidapi/CMakeLists.txt index 1f53c9b692a..f3045466e1c 100644 --- a/src/hidapi/CMakeLists.txt +++ b/src/hidapi/CMakeLists.txt @@ -15,5 +15,5 @@ add_library(hidapi STATIC ${HIDAPI_IMPL}) if (CMAKE_SYSTEM_NAME STREQUAL "Linux") # Don't link the udev library, as there are two versions out there (libudev.so.0, libudev.so.1), so they are linked explicitely. # target_link_libraries(hidapi udev) - target_link_libraries(hidapi) + target_link_libraries(hidapi dl) endif() diff --git a/src/hidapi/README.md b/src/hidapi/README.md new file mode 100644 index 00000000000..4f66b3274ac --- /dev/null +++ b/src/hidapi/README.md @@ -0,0 +1,5 @@ +** hidapi is a c++ library for communicating with USB and Bluetooth HID devices on Linux, Mac and Windows.** + +For more information go to https://github.com/libusb/hidapi + +THIS DIRECTORY CONTAINS THE hidapi-0.9.0 7da5cc9 SOURCE DISTRIBUTION. diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index 89e8c0f6296..b25d15af58d 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -51,7 +51,7 @@ const std::string MODEL_CONFIG_FILE = "Metadata/Slic3r_PE_model.config"; const std::string LAYER_HEIGHTS_PROFILE_FILE = "Metadata/Slic3r_PE_layer_heights_profile.txt"; const std::string LAYER_CONFIG_RANGES_FILE = "Metadata/Prusa_Slicer_layer_config_ranges.xml"; const std::string SLA_SUPPORT_POINTS_FILE = "Metadata/Slic3r_PE_sla_support_points.txt"; -const std::string CUSTOM_GCODE_PER_HEIGHT_FILE = "Metadata/Prusa_Slicer_custom_gcode_per_height.xml"; +const std::string CUSTOM_GCODE_PER_PRINT_Z_FILE = "Metadata/Prusa_Slicer_custom_gcode_per_print_z.xml"; const char* MODEL_TAG = "model"; const char* RESOURCES_TAG = "resources"; @@ -418,7 +418,7 @@ namespace Slic3r { void _extract_layer_config_ranges_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat); void _extract_sla_support_points_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat); - void _extract_custom_gcode_per_height_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat); + void _extract_custom_gcode_per_print_z_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat); void _extract_print_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, DynamicPrintConfig& config, const std::string& archive_filename); bool _extract_model_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, Model& model); @@ -629,10 +629,10 @@ namespace Slic3r { // extract slic3r print config file _extract_print_config_from_archive(archive, stat, config, filename); } - if (boost::algorithm::iequals(name, CUSTOM_GCODE_PER_HEIGHT_FILE)) + if (boost::algorithm::iequals(name, CUSTOM_GCODE_PER_PRINT_Z_FILE)) { // extract slic3r layer config ranges file - _extract_custom_gcode_per_height_from_archive(archive, stat); + _extract_custom_gcode_per_print_z_from_archive(archive, stat); } else if (boost::algorithm::iequals(name, MODEL_CONFIG_FILE)) { @@ -1064,7 +1064,7 @@ namespace Slic3r { return true; } - void _3MF_Importer::_extract_custom_gcode_per_height_from_archive(::mz_zip_archive &archive, const mz_zip_archive_file_stat &stat) + void _3MF_Importer::_extract_custom_gcode_per_print_z_from_archive(::mz_zip_archive &archive, const mz_zip_archive_file_stat &stat) { if (stat.m_uncomp_size > 0) { @@ -1079,24 +1079,23 @@ namespace Slic3r { pt::ptree main_tree; pt::read_xml(iss, main_tree); - if (main_tree.front().first != "custom_gcodes_per_height") + if (main_tree.front().first != "custom_gcodes_per_print_z") return; pt::ptree code_tree = main_tree.front().second; - if (!m_model->custom_gcode_per_height.empty()) - m_model->custom_gcode_per_height.clear(); + m_model->custom_gcode_per_print_z.clear(); for (const auto& code : code_tree) { if (code.first != "code") continue; pt::ptree tree = code.second; - double height = tree.get(".height"); - std::string gcode = tree.get(".gcode"); - int extruder = tree.get(".extruder"); - std::string color = tree.get(".color"); + double print_z = tree.get (".print_z" ); + std::string gcode = tree.get (".gcode" ); + int extruder = tree.get (".extruder" ); + std::string color = tree.get (".color" ); - m_model->custom_gcode_per_height.push_back(Model::CustomGCode(height, gcode, extruder, color)) ; + m_model->custom_gcode_per_print_z.push_back(Model::CustomGCode{print_z, gcode, extruder, color}) ; } } } @@ -1885,7 +1884,7 @@ namespace Slic3r { bool _add_sla_support_points_file_to_archive(mz_zip_archive& archive, Model& model); bool _add_print_config_file_to_archive(mz_zip_archive& archive, const DynamicPrintConfig &config); bool _add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model, const IdToObjectDataMap &objects_data); - bool _add_custom_gcode_per_height_file_to_archive(mz_zip_archive& archive, Model& model); + bool _add_custom_gcode_per_print_z_file_to_archive(mz_zip_archive& archive, Model& model); }; #if ENABLE_THUMBNAIL_GENERATOR @@ -1988,9 +1987,9 @@ namespace Slic3r { return false; } - // Adds custom gcode per height file ("Metadata/Prusa_Slicer_custom_gcode_per_height.xml"). + // Adds custom gcode per height file ("Metadata/Prusa_Slicer_custom_gcode_per_print_z.xml"). // All custom gcode per height of whole Model are stored here - if (!_add_custom_gcode_per_height_file_to_archive(archive, model)) + if (!_add_custom_gcode_per_print_z_file_to_archive(archive, model)) { close_zip_writer(&archive); boost::filesystem::remove(filename); @@ -2567,20 +2566,20 @@ namespace Slic3r { return true; } -bool _3MF_Exporter::_add_custom_gcode_per_height_file_to_archive( mz_zip_archive& archive, Model& model) +bool _3MF_Exporter::_add_custom_gcode_per_print_z_file_to_archive( mz_zip_archive& archive, Model& model) { std::string out = ""; - if (!model.custom_gcode_per_height.empty()) + if (!model.custom_gcode_per_print_z.empty()) { pt::ptree tree; - pt::ptree& main_tree = tree.add("custom_gcodes_per_height", ""); + pt::ptree& main_tree = tree.add("custom_gcodes_per_print_z", ""); - for (const Model::CustomGCode& code : model.custom_gcode_per_height) + for (const Model::CustomGCode& code : model.custom_gcode_per_print_z) { pt::ptree& code_tree = main_tree.add("code", ""); // store minX and maxZ - code_tree.put(".height" , code.height ); + code_tree.put(".print_z" , code.print_z ); code_tree.put(".gcode" , code.gcode ); code_tree.put(".extruder" , code.extruder ); code_tree.put(".color" , code.color ); @@ -2599,9 +2598,9 @@ bool _3MF_Exporter::_add_custom_gcode_per_height_file_to_archive( mz_zip_archive if (!out.empty()) { - if (!mz_zip_writer_add_mem(&archive, CUSTOM_GCODE_PER_HEIGHT_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION)) + if (!mz_zip_writer_add_mem(&archive, CUSTOM_GCODE_PER_PRINT_Z_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION)) { - add_error("Unable to add custom Gcodes per height file to archive"); + add_error("Unable to add custom Gcodes per print_z file to archive"); return false; } } diff --git a/src/libslic3r/Format/AMF.cpp b/src/libslic3r/Format/AMF.cpp index d50f6e395c4..aee8b74018c 100644 --- a/src/libslic3r/Format/AMF.cpp +++ b/src/libslic3r/Format/AMF.cpp @@ -637,7 +637,7 @@ void AMFParserContext::endElement(const char * /* name */) int extruder = atoi(m_value[2].c_str()); const std::string& color = m_value[3]; - m_model.custom_gcode_per_height.push_back(Model::CustomGCode(height, gcode, extruder, color)); + m_model.custom_gcode_per_print_z.push_back(Model::CustomGCode{height, gcode, extruder, color}); for (std::string& val: m_value) val.clear(); @@ -1221,21 +1221,21 @@ bool store_amf(const char *path, Model *model, const DynamicPrintConfig *config) stream << " \n"; } - if (!model->custom_gcode_per_height.empty()) + if (!model->custom_gcode_per_print_z.empty()) { std::string out = ""; pt::ptree tree; pt::ptree& main_tree = tree.add("custom_gcodes_per_height", ""); - for (const Model::CustomGCode& code : model->custom_gcode_per_height) + for (const Model::CustomGCode& code : model->custom_gcode_per_print_z) { pt::ptree& code_tree = main_tree.add("code", ""); // store minX and maxZ - code_tree.put(".height", code.height); - code_tree.put(".gcode", code.gcode); - code_tree.put(".extruder", code.extruder); - code_tree.put(".color", code.color); + code_tree.put(".print_z" , code.print_z ); + code_tree.put(".gcode" , code.gcode ); + code_tree.put(".extruder" , code.extruder ); + code_tree.put(".color" , code.color ); } if (!tree.empty()) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 91627631f4c..433422d9977 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -936,7 +936,7 @@ void GCode::_do_export(Print& print, FILE* file) // Initialize custom gcode Model* model = print.get_object(0)->model_object()->get_model(); - m_custom_g_code_heights = model->custom_gcode_per_height; + m_custom_gcode_per_print_z = model->custom_gcode_per_print_z; // Initialize autospeed. { @@ -1124,20 +1124,22 @@ void GCode::_do_export(Print& print, FILE* file) } print.throw_if_canceled(); +// #ys_FIXME_no_exported_codes + /* /* To avoid change filament for non-used extruder for Multi-material, - * check model->custom_gcode_per_height using tool_ordering values - * */ - if (!m_custom_g_code_heights. empty()) + * check model->custom_gcode_per_print_z using tool_ordering values + * / + if (!m_custom_gcode_per_print_z. empty()) { bool delete_executed = false; - auto it = m_custom_g_code_heights.end(); - while (it != m_custom_g_code_heights.begin()) + auto it = m_custom_gcode_per_print_z.end(); + while (it != m_custom_gcode_per_print_z.begin()) { --it; if (it->gcode != ColorChangeCode) continue; - auto it_layer_tools = std::lower_bound(tool_ordering.begin(), tool_ordering.end(), LayerTools(it->height)); + auto it_layer_tools = std::lower_bound(tool_ordering.begin(), tool_ordering.end(), LayerTools(it->print_z)); bool used_extruder = false; for (; it_layer_tools != tool_ordering.end(); it_layer_tools++) @@ -1154,16 +1156,16 @@ void GCode::_do_export(Print& print, FILE* file) /* If we are there, current extruder wouldn't be used, * so this color change is a redundant move. - * Delete this item from m_custom_g_code_heights - * */ - it = m_custom_g_code_heights.erase(it); + * Delete this item from m_custom_gcode_per_print_z + * / + it = m_custom_gcode_per_print_z.erase(it); delete_executed = true; } if (delete_executed) - model->custom_gcode_per_height = m_custom_g_code_heights; + model->custom_gcode_per_print_z = m_custom_gcode_per_print_z; } - +*/ m_cooling_buffer->set_current_extruder(initial_extruder_id); @@ -1461,7 +1463,7 @@ void GCode::_do_export(Print& print, FILE* file) dst.first += buf; ++ dst.second; }; - print.m_print_statistics.filament_stats.insert(std::pair(extruder.id(), (float)used_filament)); + print.m_print_statistics.filament_stats.insert(std::pair{extruder.id(), (float)used_filament}); append(out_filament_used_mm, "%.1lf", used_filament); append(out_filament_used_cm3, "%.1lf", extruded_volume * 0.001); if (filament_weight > 0.) { @@ -1835,15 +1837,15 @@ void GCode::process_layer( std::string custom_code = ""; std::string pause_print_msg = ""; int m600_before_extruder = -1; - while (!m_custom_g_code_heights.empty() && m_custom_g_code_heights.front().height-EPSILON < layer.print_z) { - custom_code = m_custom_g_code_heights.front().gcode; + while (!m_custom_gcode_per_print_z.empty() && m_custom_gcode_per_print_z.front().print_z - EPSILON < layer.print_z) { + custom_code = m_custom_gcode_per_print_z.front().gcode; - if (custom_code == ColorChangeCode && m_custom_g_code_heights.front().extruder > 0) - m600_before_extruder = m_custom_g_code_heights.front().extruder - 1; + if (custom_code == ColorChangeCode && m_custom_gcode_per_print_z.front().extruder > 0) + m600_before_extruder = m_custom_gcode_per_print_z.front().extruder - 1; if (custom_code == PausePrintCode) - pause_print_msg = m_custom_g_code_heights.front().color; + pause_print_msg = m_custom_gcode_per_print_z.front().color; - m_custom_g_code_heights.erase(m_custom_g_code_heights.begin()); + m_custom_gcode_per_print_z.erase(m_custom_gcode_per_print_z.begin()); colorprint_change = true; } diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 7f009b8147a..68bb85a988a 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -367,7 +367,7 @@ protected: * Updated before the export and erased during the process, * so no toolchange occurs twice. * */ - std::vector m_custom_g_code_heights; + std::vector m_custom_gcode_per_print_z; // Time estimators GCodeTimeEstimator m_normal_time_estimator; diff --git a/src/libslic3r/GCodeWriter.hpp b/src/libslic3r/GCodeWriter.hpp index 664b0e3a1df..98abdda280b 100644 --- a/src/libslic3r/GCodeWriter.hpp +++ b/src/libslic3r/GCodeWriter.hpp @@ -10,6 +10,11 @@ namespace Slic3r { +// Additional Codes which can be set by user using DoubleSlider +static constexpr char ColorChangeCode[] = "M600"; +static constexpr char PausePrintCode[] = "M601"; +static constexpr char ExtruderChangeCode[] = "tool_change"; + class GCodeWriter { public: GCodeConfig config; diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index ce3debfb52d..7137527e9f7 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -18,6 +18,8 @@ #include "SVG.hpp" #include +#include "GCodeWriter.hpp" +#include "GCode/PreviewData.hpp" namespace Slic3r { @@ -43,7 +45,7 @@ Model& Model::assign_copy(const Model &rhs) } // copy custom code per height - this->custom_gcode_per_height = rhs.custom_gcode_per_height; + this->custom_gcode_per_print_z = rhs.custom_gcode_per_print_z; return *this; } @@ -64,7 +66,7 @@ Model& Model::assign_copy(Model &&rhs) rhs.objects.clear(); // copy custom code per height - this->custom_gcode_per_height = rhs.custom_gcode_per_height; + this->custom_gcode_per_print_z = rhs.custom_gcode_per_print_z; return *this; } @@ -124,6 +126,8 @@ Model Model::read_from_file(const std::string& input_file, DynamicPrintConfig* c if (add_default_instances) model.add_default_instances(); + update_custom_gcode_per_print_z_from_config(model.custom_gcode_per_print_z, config); + return model; } @@ -159,6 +163,8 @@ Model Model::read_from_archive(const std::string& input_file, DynamicPrintConfig if (add_default_instances) model.add_default_instances(); + update_custom_gcode_per_print_z_from_config(model.custom_gcode_per_print_z, config); + return model; } @@ -595,16 +601,15 @@ std::string Model::propose_export_file_name_and_path(const std::string &new_exte std::vector> Model::get_custom_tool_changes(double default_layer_height, size_t num_extruders) const { std::vector> custom_tool_changes; - if (!custom_gcode_per_height.empty()) { - for (const CustomGCode& custom_gcode : custom_gcode_per_height) - if (custom_gcode.gcode == ExtruderChangeCode) { - DynamicPrintConfig config; - // If extruder count in PrinterSettings was changed, use default (0) extruder for extruders, more than num_extruders - config.set_key_value("extruder", new ConfigOptionInt(custom_gcode.extruder > num_extruders ? 0 : custom_gcode.extruder)); - // For correct extruders(tools) changing, we should decrease custom_gcode.height value by one default layer height - custom_tool_changes.push_back({ custom_gcode.height - default_layer_height, config }); - } - } + for (const CustomGCode& custom_gcode : custom_gcode_per_print_z) + if (custom_gcode.gcode == ExtruderChangeCode) { + DynamicPrintConfig config; + // If extruder count in PrinterSettings was changed, use default (0) extruder for extruders, more than num_extruders + config.set_key_value("extruder", new ConfigOptionInt(custom_gcode.extruder > num_extruders ? 0 : custom_gcode.extruder)); + // For correct extruders(tools) changing, we should decrease custom_gcode.height value by one default layer height + custom_tool_changes.push_back({ custom_gcode.print_z - default_layer_height, config }); + } + return custom_tool_changes; } @@ -1933,6 +1938,30 @@ extern bool model_has_advanced_features(const Model &model) return false; } +extern void update_custom_gcode_per_print_z_from_config(std::vector& custom_gcode_per_print_z, DynamicPrintConfig* config) +{ + if (!config->has("colorprint_heights")) + return; + + const std::vector& colors = GCodePreviewData::ColorPrintColors(); + + const auto& colorprint_values = config->option("colorprint_heights")->values; + + if (!colorprint_values.empty()) + { + custom_gcode_per_print_z.clear(); + custom_gcode_per_print_z.reserve(colorprint_values.size()); + int i = 0; + for (auto val : colorprint_values) + custom_gcode_per_print_z.emplace_back(Model::CustomGCode{ val, ColorChangeCode, 1, colors[(++i)%7] }); + } + + /* There is one and only place this configuration option is used now. + * It wouldn't be used in the future, so erase it. + * */ + config->erase("colorprint_heights"); +} + #ifndef NDEBUG // Verify whether the IDs of Model / ModelObject / ModelVolume / ModelInstance / ModelMaterial are valid and unique. void check_model_ids_validity(const Model &model) diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index c2942a4ea39..9f173f6ea07 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -749,33 +749,30 @@ public: // Extensions for color print struct CustomGCode { - CustomGCode(double height, const std::string& code, int extruder, const std::string& color) : - height(height), gcode(code), extruder(extruder), color(color) {} - - bool operator<(const CustomGCode& other) const { return other.height > this->height; } + bool operator<(const CustomGCode& other) const { return other.print_z > this->print_z; } bool operator==(const CustomGCode& other) const { - return (other.height == this->height) && - (other.gcode == this->gcode) && - (other.extruder == this->extruder )&& - (other.color == this->color ); + return (other.print_z == this->print_z ) && + (other.gcode == this->gcode ) && + (other.extruder == this->extruder ) && + (other.color == this->color ); } bool operator!=(const CustomGCode& other) const { - return (other.height != this->height) || - (other.gcode != this->gcode) || - (other.extruder != this->extruder )|| - (other.color != this->color ); + return (other.print_z != this->print_z ) || + (other.gcode != this->gcode ) || + (other.extruder != this->extruder ) || + (other.color != this->color ); } - double height; + double print_z; std::string gcode; int extruder; // 0 - "gcode" will be applied for whole print // else - "gcode" will be applied only for "extruder" print std::string color; // if gcode is equal to PausePrintCode, // this field is used for save a short message shown on Printer display }; - std::vector custom_gcode_per_height; + std::vector custom_gcode_per_print_z; // Default constructor assigns a new ID to the model. Model() { assert(this->id().valid()); } @@ -841,7 +838,7 @@ public: // Propose an output path, replace extension. The new_extension shall contain the initial dot. std::string propose_export_file_name_and_path(const std::string &new_extension) const; - // from custom_gcode_per_height get just tool_change codes + // from custom_gcode_per_print_z get just tool_change codes std::vector> get_custom_tool_changes(double default_layer_height, size_t num_extruders) const; private: @@ -877,6 +874,10 @@ extern bool model_volume_list_changed(const ModelObject &model_object_old, const extern bool model_has_multi_part_objects(const Model &model); // If the model has advanced features, then it cannot be processed in simple mode. extern bool model_has_advanced_features(const Model &model); +/* If loaded configuration has a "colorprint_heights" option (if it was imported from older Slicer), + * then model.custom_gcode_per_print_z should be updated considering this option + * */ +extern void update_custom_gcode_per_print_z_from_config(std::vector& custom_gcode_per_print_z, DynamicPrintConfig* config); #ifndef NDEBUG // Verify whether the IDs of Model / ModelObject / ModelVolume / ModelInstance / ModelMaterial are valid and unique. diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index ae32bd2d371..1d4e69763ef 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -739,10 +739,10 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ model_object_status.emplace(model_object->id(), ModelObjectStatus::Old); // But if custom gcode per layer height was changed - if (m_model.custom_gcode_per_height != model.custom_gcode_per_height) { + if (m_model.custom_gcode_per_print_z != model.custom_gcode_per_print_z) { // we should stop background processing update_apply_status(this->invalidate_step(psGCodeExport)); - m_model.custom_gcode_per_height = model.custom_gcode_per_height; + m_model.custom_gcode_per_print_z = model.custom_gcode_per_print_z; } } else if (model_object_list_extended(m_model, model)) { // Add new objects. Their volumes and configs will be synchronized later. diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 9f3bc05391a..5f5a861da3c 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -71,12 +71,6 @@ enum SLAPillarConnectionMode { slapcmDynamic }; -// ys_FIXME ! may be, it's not a best place -// Additional Codes which can be set by user using DoubleSlider -static const std::string ColorChangeCode = "M600"; -static const std::string PausePrintCode = "M601"; -static const std::string ExtruderChangeCode = "tool_change"; - template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { static t_config_enum_values keys_map; if (keys_map.empty()) { diff --git a/src/libslic3r/ShortestPath.cpp b/src/libslic3r/ShortestPath.cpp index 8b5cbf483ca..e9df4c5b5ce 100644 --- a/src/libslic3r/ShortestPath.cpp +++ b/src/libslic3r/ShortestPath.cpp @@ -43,6 +43,7 @@ std::vector> chain_segments_closest_point(std::vector> chain_segments_greedy_constrained_reversals else if (num_segments == 1) { // Just sort the end points so that the first point visited is closest to start_near. - out.emplace_back(0, start_near != nullptr && + out.emplace_back(0, could_reverse_func(0) && start_near != nullptr && (end_point_func(0, true) - *start_near).template cast().squaredNorm() < (end_point_func(0, false) - *start_near).template cast().squaredNorm()); } else @@ -999,13 +1000,13 @@ std::vector> chain_extrusion_entities(std::vector const Point& { return first_point ? entities[idx]->first_point() : entities[idx]->last_point(); }; auto could_reverse = [&entities](size_t idx) { const ExtrusionEntity *ee = entities[idx]; return ee->is_loop() || ee->can_reverse(); }; std::vector> out = chain_segments_greedy_constrained_reversals(segment_end_point, could_reverse, entities.size(), start_near); - for (size_t i = 0; i < entities.size(); ++ i) { - ExtrusionEntity *ee = entities[i]; + for (std::pair &segment : out) { + ExtrusionEntity *ee = entities[segment.first]; if (ee->is_loop()) // Ignore reversals for loops, as the start point equals the end point. - out[i].second = false; + segment.second = false; // Is can_reverse() respected by the reversals? - assert(entities[i]->can_reverse() || ! out[i].second); + assert(ee->can_reverse() || ! segment.second); } return out; } diff --git a/src/libslic3r/Slicing.cpp b/src/libslic3r/Slicing.cpp index 9af6048abf4..8199bde031a 100644 --- a/src/libslic3r/Slicing.cpp +++ b/src/libslic3r/Slicing.cpp @@ -224,38 +224,14 @@ std::vector layer_height_profile_from_ranges( // Based on the work of @platsch // Fill layer_height_profile by heights ensuring a prescribed maximum cusp height. -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -std::vector layer_height_profile_adaptive(const SlicingParameters& slicing_params, - const ModelObject& object, float cusp_value) -#else -std::vector layer_height_profile_adaptive( - const SlicingParameters &slicing_params, - const t_layer_config_ranges & /* layer_config_ranges */, - const ModelVolumePtrs &volumes) -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE +std::vector layer_height_profile_adaptive(const SlicingParameters& slicing_params, const ModelObject& object, float quality_factor) { -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE // 1) Initialize the SlicingAdaptive class with the object meshes. SlicingAdaptive as; as.set_slicing_parameters(slicing_params); - as.set_object(object); -#else - // 1) Initialize the SlicingAdaptive class with the object meshes. - SlicingAdaptive as; - as.set_slicing_parameters(slicing_params); - for (const ModelVolume* volume : volumes) - if (volume->is_model_part()) - as.add_mesh(&volume->mesh()); -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - - as.prepare(); + as.prepare(object); // 2) Generate layers using the algorithm of @platsch - // loop until we have at least one layer and the max slice_z reaches the object height -#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - double cusp_value = 0.2; -#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - std::vector layer_height_profile; layer_height_profile.push_back(0.0); layer_height_profile.push_back(slicing_params.first_object_layer_height); @@ -263,39 +239,41 @@ std::vector layer_height_profile_adaptive( layer_height_profile.push_back(slicing_params.first_object_layer_height); layer_height_profile.push_back(slicing_params.first_object_layer_height); } - double slice_z = slicing_params.first_object_layer_height; - int current_facet = 0; -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - while (slice_z <= slicing_params.object_print_z_height()) { - double height = slicing_params.max_layer_height; -#else - double height = slicing_params.first_object_layer_height; - while ((slice_z - height) <= slicing_params.object_print_z_height()) { - height = 999.0; -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + double print_z = slicing_params.first_object_layer_height; + // last facet visited by the as.next_layer_height() function, where the facets are sorted by their increasing Z span. + size_t current_facet = 0; + // loop until we have at least one layer and the max slice_z reaches the object height + while (print_z + EPSILON < slicing_params.object_print_z_height()) { + float height = slicing_params.max_layer_height; // Slic3r::debugf "\n Slice layer: %d\n", $id; // determine next layer height - double cusp_height = as.cusp_height((float)slice_z, cusp_value, current_facet); + float cusp_height = as.next_layer_height(float(print_z), quality_factor, current_facet); +#if 0 // check for horizontal features and object size - /* - if($self->config->get_value('match_horizontal_surfaces')) { - my $horizontal_dist = $adaptive_slicing[$region_id]->horizontal_facet_distance(scale $slice_z+$cusp_height, $min_height); - if(($horizontal_dist < $min_height) && ($horizontal_dist > 0)) { - Slic3r::debugf "Horizontal feature ahead, distance: %f\n", $horizontal_dist; - # can we shrink the current layer a bit? - if($cusp_height-($min_height-$horizontal_dist) > $min_height) { - # yes we can - $cusp_height = $cusp_height-($min_height-$horizontal_dist); - Slic3r::debugf "Shrink layer height to %f\n", $cusp_height; - }else{ - # no, current layer would become too thin - $cusp_height = $cusp_height+$horizontal_dist; - Slic3r::debugf "Widen layer height to %f\n", $cusp_height; + if (this->config.match_horizontal_surfaces.value) { + coordf_t horizontal_dist = as.horizontal_facet_distance(print_z + height, min_layer_height); + if ((horizontal_dist < min_layer_height) && (horizontal_dist > 0)) { + #ifdef SLIC3R_DEBUG + std::cout << "Horizontal feature ahead, distance: " << horizontal_dist << std::endl; + #endif + // can we shrink the current layer a bit? + if (height-(min_layer_height - horizontal_dist) > min_layer_height) { + // yes we can + height -= (min_layer_height - horizontal_dist); + #ifdef SLIC3R_DEBUG + std::cout << "Shrink layer height to " << height << std::endl; + #endif + } else { + // no, current layer would become too thin + height += horizontal_dist; + #ifdef SLIC3R_DEBUG + std::cout << "Widen layer height to " << height << std::endl; + #endif } } } - */ +#endif height = std::min(cusp_height, height); // apply z-gradation @@ -308,22 +286,22 @@ std::vector layer_height_profile_adaptive( // look for an applicable custom range /* - if (my $range = first { $_->[0] <= $slice_z && $_->[1] > $slice_z } @{$self->layer_height_ranges}) { + if (my $range = first { $_->[0] <= $print_z && $_->[1] > $print_z } @{$self->layer_height_ranges}) { $height = $range->[2]; # if user set custom height to zero we should just skip the range and resume slicing over it if ($height == 0) { - $slice_z += $range->[1] - $range->[0]; + $print_z += $range->[1] - $range->[0]; next; } } */ - layer_height_profile.push_back(slice_z); + layer_height_profile.push_back(print_z); layer_height_profile.push_back(height); - slice_z += height; + print_z += height; #if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - layer_height_profile.push_back(slice_z); + layer_height_profile.push_back(print_z); layer_height_profile.push_back(height); #endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE } @@ -722,11 +700,7 @@ int generate_layer_height_texture( const Vec3crd &color1 = palette_raw[idx1]; const Vec3crd &color2 = palette_raw[idx2]; coordf_t z = cell_to_z * coordf_t(cell); -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - assert((lo - EPSILON <= z) && (z <= hi + EPSILON)); -#else - assert(z >= lo && z <= hi); -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + assert(lo - EPSILON <= z && z <= hi + EPSILON); // Intensity profile to visualize the layers. coordf_t intensity = cos(M_PI * 0.7 * (mid - z) / h); // Color mapping from layer height to RGB. diff --git a/src/libslic3r/Slicing.hpp b/src/libslic3r/Slicing.hpp index 03ef7e67d6b..036344b224a 100644 --- a/src/libslic3r/Slicing.hpp +++ b/src/libslic3r/Slicing.hpp @@ -18,12 +18,7 @@ namespace Slic3r class PrintConfig; class PrintObjectConfig; -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE class ModelObject; -#else -class ModelVolume; -typedef std::vector ModelVolumePtrs; -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE // Parameters to guide object slicing and support generation. // The slicing parameters account for a raft and whether the 1st object layer is printed with a normal or a bridging flow @@ -142,10 +137,9 @@ extern std::vector layer_height_profile_from_ranges( const SlicingParameters &slicing_params, const t_layer_config_ranges &layer_config_ranges); -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE extern std::vector layer_height_profile_adaptive( const SlicingParameters& slicing_params, - const ModelObject& object, float cusp_value); + const ModelObject& object, float quality_factor); struct HeightProfileSmoothingParams { @@ -159,12 +153,6 @@ struct HeightProfileSmoothingParams extern std::vector smooth_height_profile( const std::vector& profile, const SlicingParameters& slicing_params, const HeightProfileSmoothingParams& smoothing_params); -#else -extern std::vector layer_height_profile_adaptive( - const SlicingParameters &slicing_params, - const t_layer_config_ranges &layer_config_ranges, - const ModelVolumePtrs &volumes); -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE enum LayerHeightEditActionType : unsigned int { LAYER_HEIGHT_EDIT_ACTION_INCREASE = 0, diff --git a/src/libslic3r/SlicingAdaptive.cpp b/src/libslic3r/SlicingAdaptive.cpp index b6ebf1ac097..7ab0c47b270 100644 --- a/src/libslic3r/SlicingAdaptive.cpp +++ b/src/libslic3r/SlicingAdaptive.cpp @@ -1,156 +1,211 @@ #include "libslic3r.h" -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE #include "Model.hpp" -#else #include "TriangleMesh.hpp" -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE #include "SlicingAdaptive.hpp" +#include + +// Based on the work of Florens Waserfall (@platch on github) +// and his paper +// Florens Wasserfall, Norman Hendrich, Jianwei Zhang: +// Adaptive Slicing for the FDM Process Revisited +// 13th IEEE Conference on Automation Science and Engineering (CASE-2017), August 20-23, Xi'an, China. DOI: 10.1109/COASE.2017.8256074 +// https://tams.informatik.uni-hamburg.de/publications/2017/Adaptive%20Slicing%20for%20the%20FDM%20Process%20Revisited.pdf + +// Vojtech believes that there is a bug in @platch's derivation of the triangle area error metric. +// Following Octave code paints graphs of recommended layer height versus surface slope angle. +#if 0 +adeg=0:1:85; +a=adeg*pi/180; +t=tan(a); +tsqr=sqrt(tan(a)); +lerr=1./cos(a); +lerr2=1./(0.3+cos(a)); +plot(adeg, t, 'b', adeg, sqrt(t), 'g', adeg, 0.5 * lerr, 'm', adeg, 0.5 * lerr2, 'r') +xlabel("angle(deg), 0 - horizontal wall, 90 - vertical wall"); +ylabel("layer height"); +legend("tan(a) as cura - topographic lines distance limit", "sqrt(tan(a)) as PrusaSlicer - error triangle area limit", "old slic3r - max distance metric", "new slic3r - Waserfall paper"); +#endif + +#ifndef NDEBUG + #define ADAPTIVE_LAYER_HEIGHT_DEBUG +#endif /* NDEBUG */ + namespace Slic3r { -#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -void SlicingAdaptive::clear() -{ - m_meshes.clear(); - m_faces.clear(); - m_face_normal_z.clear(); -} -#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - -std::pair face_z_span(const stl_facet *f) +static inline std::pair face_z_span(const stl_facet &f) { return std::pair( - std::min(std::min(f->vertex[0](2), f->vertex[1](2)), f->vertex[2](2)), - std::max(std::max(f->vertex[0](2), f->vertex[1](2)), f->vertex[2](2))); + std::min(std::min(f.vertex[0](2), f.vertex[1](2)), f.vertex[2](2)), + std::max(std::max(f.vertex[0](2), f.vertex[1](2)), f.vertex[2](2))); } -void SlicingAdaptive::prepare() +// By Florens Waserfall aka @platch: +// This constant essentially describes the volumetric error at the surface which is induced +// by stacking "elliptic" extrusion threads. It is empirically determined by +// 1. measuring the surface profile of printed parts to find +// the ratio between layer height and profile height and then +// 2. computing the geometric difference between the model-surface and the elliptic profile. +// +// The definition of the roughness formula is in +// https://tams.informatik.uni-hamburg.de/publications/2017/Adaptive%20Slicing%20for%20the%20FDM%20Process%20Revisited.pdf +// (page 51, formula (8)) +// Currenty @platch's error metric formula is not used. +static constexpr double SURFACE_CONST = 0.18403; + +// for a given facet, compute maximum height within the allowed surface roughness / stairstepping deviation +static inline float layer_height_from_slope(const SlicingAdaptive::FaceZ &face, float max_surface_deviation) { -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - if (m_object == nullptr) - return; +// @platch's formula, see his paper "Adaptive Slicing for the FDM Process Revisited". +// return float(max_surface_deviation / (SURFACE_CONST + 0.5 * std::abs(normal_z))); + +// Constant stepping in horizontal direction, as used by Cura. +// return (face.n_cos > 1e-5) ? float(max_surface_deviation * face.n_sin / face.n_cos) : FLT_MAX; - m_faces.clear(); - m_face_normal_z.clear(); +// Constant error measured as an area of the surface error triangle, Vojtech's formula. +// return (face.n_cos > 1e-5) ? float(1.44 * max_surface_deviation * sqrt(face.n_sin / face.n_cos)) : FLT_MAX; - m_mesh = m_object->raw_mesh(); - const ModelInstance* first_instance = m_object->instances.front(); - m_mesh.transform(first_instance->get_matrix(), first_instance->is_left_handed()); +// Constant error measured as an area of the surface error triangle, Vojtech's formula with clamping to roughness at 90 degrees. + return std::min(max_surface_deviation / 0.184f, (face.n_cos > 1e-5) ? float(1.44 * max_surface_deviation * sqrt(face.n_sin / face.n_cos)) : FLT_MAX); + +// Constant stepping along the surface, equivalent to the "surface roughness" metric by Perez and later Pandey et all, see @platch's paper for references. +// return float(max_surface_deviation * face.n_sin); +} + +void SlicingAdaptive::clear() +{ + m_faces.clear(); +} + +void SlicingAdaptive::prepare(const ModelObject &object) +{ + this->clear(); + + TriangleMesh mesh = object.raw_mesh(); + const ModelInstance &first_instance = *object.instances.front(); + mesh.transform(first_instance.get_matrix(), first_instance.is_left_handed()); // 1) Collect faces from mesh. - m_faces.reserve(m_mesh.stl.stats.number_of_facets); - for (stl_facet& face : m_mesh.stl.facet_start) - { - face.normal.normalize(); - m_faces.emplace_back(&face); + m_faces.reserve(mesh.stl.stats.number_of_facets); + for (const stl_facet &face : mesh.stl.facet_start) { + Vec3f n = face.normal.normalized(); + m_faces.emplace_back(FaceZ({ face_z_span(face), std::abs(n.z()), std::sqrt(n.x() * n.x() + n.y() * n.y()) })); } -#else - // 1) Collect faces of all meshes. - int nfaces_total = 0; - for (std::vector::const_iterator it_mesh = m_meshes.begin(); it_mesh != m_meshes.end(); ++ it_mesh) - nfaces_total += (*it_mesh)->stl.stats.number_of_facets; - m_faces.reserve(nfaces_total); - for (std::vector::const_iterator it_mesh = m_meshes.begin(); it_mesh != m_meshes.end(); ++ it_mesh) - for (const stl_facet& face : (*it_mesh)->stl.facet_start) - m_faces.emplace_back(&face); -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE // 2) Sort faces lexicographically by their Z span. - std::sort(m_faces.begin(), m_faces.end(), [](const stl_facet *f1, const stl_facet *f2) { return face_z_span(f1) < face_z_span(f2); }); - - // 3) Generate Z components of the facet normals. - m_face_normal_z.assign(m_faces.size(), 0.0f); - for (size_t iface = 0; iface < m_faces.size(); ++ iface) - m_face_normal_z[iface] = m_faces[iface]->normal(2); + std::sort(m_faces.begin(), m_faces.end(), [](const FaceZ &f1, const FaceZ &f2) { return f1.z_span < f2.z_span; }); } -float SlicingAdaptive::cusp_height(float z, float cusp_value, int ¤t_facet) +// current_facet is in/out parameter, rememebers the index of the last face of m_faces visited, +// where this function will start from. +// print_z - the top print surface of the previous layer. +// returns height of the next layer. +float SlicingAdaptive::next_layer_height(const float print_z, float quality_factor, size_t ¤t_facet) { - float height = (float)m_slicing_params.max_layer_height; - bool first_hit = false; + float height = (float)m_slicing_params.max_layer_height; + + float max_surface_deviation; + + { +#if 0 +// @platch's formula for quality: + double delta_min = SURFACE_CONST * m_slicing_params.min_layer_height; + double delta_mid = (SURFACE_CONST + 0.5) * m_slicing_params.layer_height; + double delta_max = (SURFACE_CONST + 0.5) * m_slicing_params.max_layer_height; +#else +// Vojtech's formula for triangle area error metric. + double delta_min = m_slicing_params.min_layer_height; + double delta_mid = m_slicing_params.layer_height; + double delta_max = m_slicing_params.max_layer_height; +#endif + max_surface_deviation = (quality_factor < 0.5f) ? + lerp(delta_min, delta_mid, 2. * quality_factor) : + lerp(delta_max, delta_mid, 2. * (1. - quality_factor)); + } // find all facets intersecting the slice-layer - int ordered_id = current_facet; - for (; ordered_id < int(m_faces.size()); ++ ordered_id) { - std::pair zspan = face_z_span(m_faces[ordered_id]); - // facet's minimum is higher than slice_z -> end loop - if (zspan.first >= z) - break; - // facet's maximum is higher than slice_z -> store the first event for next cusp_height call to begin at this point - if (zspan.second > z) { - // first event? - if (! first_hit) { - first_hit = true; - current_facet = ordered_id; - } - // skip touching facets which could otherwise cause small cusp values - if (zspan.second <= z + EPSILON) - continue; - // compute cusp-height for this facet and store minimum of all heights - float normal_z = m_face_normal_z[ordered_id]; - height = std::min(height, (normal_z == 0.0f) ? (float)m_slicing_params.max_layer_height : std::abs(cusp_value / normal_z)); - } + size_t ordered_id = current_facet; + { + bool first_hit = false; + for (; ordered_id < m_faces.size(); ++ ordered_id) { + const std::pair &zspan = m_faces[ordered_id].z_span; + // facet's minimum is higher than slice_z -> end loop + if (zspan.first >= print_z) + break; + // facet's maximum is higher than slice_z -> store the first event for next cusp_height call to begin at this point + if (zspan.second > print_z) { + // first event? + if (! first_hit) { + first_hit = true; + current_facet = ordered_id; + } + // skip touching facets which could otherwise cause small cusp values + if (zspan.second < print_z + EPSILON) + continue; + // compute cusp-height for this facet and store minimum of all heights + height = std::min(height, layer_height_from_slope(m_faces[ordered_id], max_surface_deviation)); + } + } } // lower height limit due to printer capabilities height = std::max(height, float(m_slicing_params.min_layer_height)); // check for sloped facets inside the determined layer and correct height if necessary - if (height > m_slicing_params.min_layer_height) { - for (; ordered_id < int(m_faces.size()); ++ ordered_id) { - std::pair zspan = face_z_span(m_faces[ordered_id]); + if (height > float(m_slicing_params.min_layer_height)) { + for (; ordered_id < m_faces.size(); ++ ordered_id) { + const std::pair &zspan = m_faces[ordered_id].z_span; // facet's minimum is higher than slice_z + height -> end loop - if (zspan.first >= z + height) + if (zspan.first >= print_z + height) break; // skip touching facets which could otherwise cause small cusp values - if (zspan.second <= z + EPSILON) + if (zspan.second < print_z + EPSILON) continue; // Compute cusp-height for this facet and check against height. - float normal_z = m_face_normal_z[ordered_id]; - float cusp = (normal_z == 0.0f) ? (float)m_slicing_params.max_layer_height : std::abs(cusp_value / normal_z); + float reduced_height = layer_height_from_slope(m_faces[ordered_id], max_surface_deviation); - float z_diff = zspan.first - z; - - // handle horizontal facets - if (normal_z > 0.999f) { - // Slic3r::debugf "cusp computation, height is reduced from %f", $height; + float z_diff = zspan.first - print_z; + if (reduced_height < z_diff) { + assert(z_diff < height + EPSILON); + // The currently visited triangle's slope limits the next layer height so much, that + // the lowest point of the currently visible triangle is already above the newly proposed layer height. + // This means, that we need to limit the layer height so that the offending newly visited triangle + // is just above of the new layer. +#ifdef ADAPTIVE_LAYER_HEIGHT_DEBUG + BOOST_LOG_TRIVIAL(trace) << "cusp computation, height is reduced from " << height << "to " << z_diff << " due to z-diff"; +#endif /* ADAPTIVE_LAYER_HEIGHT_DEBUG */ height = z_diff; - // Slic3r::debugf "to %f due to near horizontal facet\n", $height; - } else if (cusp > z_diff) { - if (cusp < height) { - // Slic3r::debugf "cusp computation, height is reduced from %f", $height; - height = cusp; - // Slic3r::debugf "to %f due to new cusp height\n", $height; - } - } else { - // Slic3r::debugf "cusp computation, height is reduced from %f", $height; - height = z_diff; - // Slic3r::debugf "to z-diff: %f\n", $height; + } else if (reduced_height < height) { +#ifdef ADAPTIVE_LAYER_HEIGHT_DEBUG + BOOST_LOG_TRIVIAL(trace) << "adaptive layer computation: height is reduced from " << height << "to " << reduced_height << " due to higher facet"; +#endif /* ADAPTIVE_LAYER_HEIGHT_DEBUG */ + height = reduced_height; } } // lower height limit due to printer capabilities again height = std::max(height, float(m_slicing_params.min_layer_height)); } -// Slic3r::debugf "cusp computation, layer-bottom at z:%f, cusp_value:%f, resulting layer height:%f\n", unscale $z, $cusp_value, $height; +#ifdef ADAPTIVE_LAYER_HEIGHT_DEBUG + BOOST_LOG_TRIVIAL(trace) << "adaptive layer computation, layer-bottom at z:" << print_z << ", quality_factor:" << quality_factor << ", resulting layer height:" << height; +#endif /* ADAPTIVE_LAYER_HEIGHT_DEBUG */ return height; } -#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE // Returns the distance to the next horizontal facet in Z-dir // to consider horizontal object features in slice thickness float SlicingAdaptive::horizontal_facet_distance(float z) { for (size_t i = 0; i < m_faces.size(); ++ i) { - std::pair zspan = face_z_span(m_faces[i]); + std::pair zspan = m_faces[i].z_span; // facet's minimum is higher than max forward distance -> end loop if (zspan.first > z + m_slicing_params.max_layer_height) break; // min_z == max_z -> horizontal facet - if ((zspan.first > z) && (zspan.first == zspan.second)) + if (zspan.first > z && zspan.first == zspan.second) return zspan.first - z; } @@ -158,6 +213,5 @@ float SlicingAdaptive::horizontal_facet_distance(float z) return (z + (float)m_slicing_params.max_layer_height > (float)m_slicing_params.object_print_z_height()) ? std::max((float)m_slicing_params.object_print_z_height() - z, 0.f) : (float)m_slicing_params.max_layer_height; } -#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE }; // namespace Slic3r diff --git a/src/libslic3r/SlicingAdaptive.hpp b/src/libslic3r/SlicingAdaptive.hpp index 1d2996986f5..a296553d62f 100644 --- a/src/libslic3r/SlicingAdaptive.hpp +++ b/src/libslic3r/SlicingAdaptive.hpp @@ -5,50 +5,36 @@ #include "Slicing.hpp" #include "admesh/stl.h" -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -#include "TriangleMesh.hpp" -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE namespace Slic3r { -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE class ModelVolume; -#else -class TriangleMesh; -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE class SlicingAdaptive { public: -#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - void clear(); -#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - void set_slicing_parameters(SlicingParameters params) { m_slicing_params = params; } -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - void set_object(const ModelObject& object) { m_object = &object; } -#else - void add_mesh(const TriangleMesh* mesh) { m_meshes.push_back(mesh); } -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - void prepare(); - float cusp_height(float z, float cusp_value, int ¤t_facet); -#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + void clear(); + void set_slicing_parameters(SlicingParameters params) { m_slicing_params = params; } + void prepare(const ModelObject &object); + // Return next layer height starting from the last print_z, using a quality measure + // (quality in range from 0 to 1, 0 - highest quality at low layer heights, 1 - lowest print quality at high layer heights). + // The layer height curve shall be centered roughly around the default profile's layer height for quality 0.5. + float next_layer_height(const float print_z, float quality, size_t ¤t_facet); float horizontal_facet_distance(float z); -#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + + struct FaceZ { + std::pair z_span; + // Cosine of the normal vector towards the Z axis. + float n_cos; + // Sine of the normal vector towards the Z axis. + float n_sin; + }; protected: - SlicingParameters m_slicing_params; + SlicingParameters m_slicing_params; -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - const ModelObject* m_object; - TriangleMesh m_mesh; -#else - std::vector m_meshes; -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - // Collected faces of all meshes, sorted by raising Z of the bottom most face. - std::vector m_faces; - // Z component of face normals, normalized. - std::vector m_face_normal_z; + std::vector m_faces; }; }; // namespace Slic3r diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 0ec8b36ee3f..d503f0c64a0 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -53,4 +53,7 @@ // Enable selection for missing files in reload from disk command #define ENABLE_RELOAD_FROM_DISK_MISSING_SELECTION (1 && ENABLE_2_2_0_ALPHA1) +// Enable closing 3Dconnextion imgui settings dialog by clicking on [X] and [Close] buttons +#define ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG (1 && ENABLE_2_2_0_ALPHA1) + #endif // _technologies_h_ diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index e587509ac77..a8b88dd037f 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -94,12 +94,13 @@ void BackgroundSlicingProcess::process_fff() m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data); #endif // ENABLE_THUMBNAIL_GENERATOR - if (m_fff_print->model().custom_gcode_per_height != GUI::wxGetApp().model().custom_gcode_per_height) { - GUI::wxGetApp().model().custom_gcode_per_height = m_fff_print->model().custom_gcode_per_height; - // #ys_FIXME : controll text + /* #ys_FIXME_no_exported_codes + if (m_fff_print->model().custom_gcode_per_print_z != GUI::wxGetApp().model().custom_gcode_per_print_z) { + GUI::wxGetApp().model().custom_gcode_per_print_z = m_fff_print->model().custom_gcode_per_print_z; GUI::show_info(nullptr, _(L("To except of redundant tool manipulation, \n" "Color change(s) for unused extruder(s) was(were) deleted")), _(L("Info"))); } + */ if (this->set_step_started(bspsGCodeFinalize)) { if (! m_export_path.empty()) { diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index a28bb61f28f..5b27c8870c4 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -133,7 +133,7 @@ GLCanvas3D::LayersEditing::LayersEditing() , m_slicing_parameters(nullptr) , m_layer_height_profile_modified(false) #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - , m_adaptive_cusp(0.0f) + , m_adaptive_quality(0.5f) #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE , state(Unknown) , band_width(2.0f) @@ -268,24 +268,24 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const ImGui::Separator(); if (imgui.button(_(L("Adaptive")))) - wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), Event(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, m_adaptive_cusp)); + wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), Event(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, m_adaptive_quality)); ImGui::SameLine(); float text_align = ImGui::GetCursorPosX(); ImGui::AlignTextToFramePadding(); - imgui.text(_(L("Cusp (mm)"))); + imgui.text(_(L("Quality / Speed"))); if (ImGui::IsItemHovered()) { ImGui::BeginTooltip(); - ImGui::TextUnformatted(_(L("I am a tooltip"))); + ImGui::TextUnformatted(_(L("Higher print quality versus higher print speed."))); ImGui::EndTooltip(); } ImGui::SameLine(); float widget_align = ImGui::GetCursorPosX(); ImGui::PushItemWidth(imgui.get_style_scaling() * 120.0f); - m_adaptive_cusp = clamp(0.0f, 0.5f * (float)m_slicing_parameters->layer_height, m_adaptive_cusp); - ImGui::SliderFloat("", &m_adaptive_cusp, 0.0f, 0.5f * (float)m_slicing_parameters->layer_height, "%.3f"); + m_adaptive_quality = clamp(0.0f, 1.f, m_adaptive_quality); + ImGui::SliderFloat("", &m_adaptive_quality, 0.0f, 1.f, "%.2f"); ImGui::Separator(); if (imgui.button(_(L("Smooth")))) @@ -645,10 +645,10 @@ void GLCanvas3D::LayersEditing::reset_layer_height_profile(GLCanvas3D& canvas) } #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -void GLCanvas3D::LayersEditing::adaptive_layer_height_profile(GLCanvas3D& canvas, float cusp) +void GLCanvas3D::LayersEditing::adaptive_layer_height_profile(GLCanvas3D& canvas, float quality_factor) { this->update_slicing_parameters(); - m_layer_height_profile = layer_height_profile_adaptive(*m_slicing_parameters, *m_model_object, cusp); + m_layer_height_profile = layer_height_profile_adaptive(*m_slicing_parameters, *m_model_object, quality_factor); const_cast(m_model_object)->layer_height_profile = m_layer_height_profile; m_layers_texture.valid = false; canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); @@ -712,11 +712,6 @@ void GLCanvas3D::LayersEditing::update_slicing_parameters() m_slicing_parameters = new SlicingParameters(); *m_slicing_parameters = PrintObject::slicing_parameters(*m_config, *m_model_object, m_object_max_z); } - -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - if (m_adaptive_cusp == 0.0f) - m_adaptive_cusp = 0.25f * m_slicing_parameters->layer_height; -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE } float GLCanvas3D::LayersEditing::thickness_bar_width(const GLCanvas3D &canvas) @@ -1016,24 +1011,25 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_items( const GLCanvas3D std::vector& colors, std::vector& cp_legend_items) { - std::vector custom_gcode_per_height = wxGetApp().plater()->model().custom_gcode_per_height; + std::vector custom_gcode_per_print_z = wxGetApp().plater()->model().custom_gcode_per_print_z; const int extruders_cnt = wxGetApp().extruders_edited_cnt(); if (extruders_cnt == 1) { - if (custom_gcode_per_height.empty()) { - cp_legend_items.push_back(I18N::translate_utf8(L("Default print color"))); + if (custom_gcode_per_print_z.empty()) { + cp_legend_items.emplace_back(I18N::translate_utf8(L("Default print color"))); colors = colors_in; return; } std::vector> cp_values; + cp_values.reserve(custom_gcode_per_print_z.size()); std::vector print_zs = canvas.get_current_print_zs(true); - for (auto custom_code : custom_gcode_per_height) + for (auto custom_code : custom_gcode_per_print_z) { if (custom_code.gcode != ColorChangeCode) continue; - auto lower_b = std::lower_bound(print_zs.begin(), print_zs.end(), custom_code.height - DoubleSlider::epsilon()); + auto lower_b = std::lower_bound(print_zs.begin(), print_zs.end(), custom_code.print_z - DoubleSlider::epsilon()); if (lower_b == print_zs.end()) continue; @@ -1044,14 +1040,14 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_items( const GLCanvas3D // to avoid duplicate values, check adding values if (cp_values.empty() || !(cp_values.back().first == previous_z && cp_values.back().second == current_z)) - cp_values.push_back(std::pair(previous_z, current_z)); + cp_values.emplace_back(std::pair(previous_z, current_z)); } const auto items_cnt = (int)cp_values.size(); if (items_cnt == 0) // There is no one color change, but there is/are some pause print or custom Gcode { - cp_legend_items.push_back(I18N::translate_utf8(L("Default print color"))); - cp_legend_items.push_back(I18N::translate_utf8(L("Pause print or custom G-code"))); + cp_legend_items.emplace_back(I18N::translate_utf8(L("Default print color"))); + cp_legend_items.emplace_back(I18N::translate_utf8(L("Pause print or custom G-code"))); colors = colors_in; return; } @@ -1060,7 +1056,7 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_items( const GLCanvas3D colors.resize(colors_in.size(), 0.0); ::memcpy((void*)(colors.data()), (const void*)(colors_in.data() + (color_cnt - 1) * 4), 4 * sizeof(float)); - cp_legend_items.push_back(I18N::translate_utf8(L("Pause print or custom G-code"))); + cp_legend_items.emplace_back(I18N::translate_utf8(L("Pause print or custom G-code"))); size_t color_pos = 4; for (int i = items_cnt; i >= 0; --i, color_pos+=4) @@ -1072,15 +1068,15 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_items( const GLCanvas3D std::string id_str = std::to_string(i + 1) + ": "; if (i == 0) { - cp_legend_items.push_back(id_str + (boost::format(I18N::translate_utf8(L("up to %.2f mm"))) % cp_values[0].first).str()); + cp_legend_items.emplace_back(id_str + (boost::format(I18N::translate_utf8(L("up to %.2f mm"))) % cp_values[0].first).str()); break; } if (i == items_cnt) { - cp_legend_items.push_back(id_str + (boost::format(I18N::translate_utf8(L("above %.2f mm"))) % cp_values[i - 1].second).str()); + cp_legend_items.emplace_back(id_str + (boost::format(I18N::translate_utf8(L("above %.2f mm"))) % cp_values[i - 1].second).str()); continue; } - cp_legend_items.push_back(id_str + (boost::format(I18N::translate_utf8(L("%.2f - %.2f mm"))) % cp_values[i - 1].second % cp_values[i].first).str()); + cp_legend_items.emplace_back(id_str + (boost::format(I18N::translate_utf8(L("%.2f - %.2f mm"))) % cp_values[i - 1].second % cp_values[i].first).str()); } } else @@ -1094,20 +1090,20 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_items( const GLCanvas3D size_t color_in_pos = 4 * (color_cnt - 1); for (unsigned int i = 0; i < (unsigned int)extruders_cnt; ++i) - cp_legend_items.push_back((boost::format(I18N::translate_utf8(L("Extruder %d"))) % (i + 1)).str()); + cp_legend_items.emplace_back((boost::format(I18N::translate_utf8(L("Extruder %d"))) % (i + 1)).str()); ::memcpy((void*)(colors.data() + color_pos), (const void*)(colors_in.data() + color_in_pos), 4 * sizeof(float)); color_pos += 4; color_in_pos -= 4; - cp_legend_items.push_back(I18N::translate_utf8(L("Pause print or custom G-code"))); + cp_legend_items.emplace_back(I18N::translate_utf8(L("Pause print or custom G-code"))); - int cnt = custom_gcode_per_height.size(); + int cnt = custom_gcode_per_print_z.size(); for (int i = cnt-1; i >= 0; --i) - if (custom_gcode_per_height[i].gcode == ColorChangeCode) { + if (custom_gcode_per_print_z[i].gcode == ColorChangeCode) { ::memcpy((void*)(colors.data() + color_pos), (const void*)(colors_in.data() + color_in_pos), 4 * sizeof(float)); color_pos += 4; color_in_pos -= 4; - cp_legend_items.push_back((boost::format(I18N::translate_utf8(L("Color change for Extruder %d at %.2f mm"))) % custom_gcode_per_height[i].extruder % custom_gcode_per_height[i].height).str()); + cp_legend_items.emplace_back((boost::format(I18N::translate_utf8(L("Color change for Extruder %d at %.2f mm"))) % custom_gcode_per_print_z[i].extruder % custom_gcode_per_print_z[i].print_z).str()); } } } @@ -1688,10 +1684,10 @@ void GLCanvas3D::reset_layer_height_profile() m_dirty = true; } -void GLCanvas3D::adaptive_layer_height_profile(float cusp) +void GLCanvas3D::adaptive_layer_height_profile(float quality_factor) { wxGetApp().plater()->take_snapshot(_(L("Variable layer height - Adaptive"))); - m_layers_editing.adaptive_layer_height_profile(*this, cusp); + m_layers_editing.adaptive_layer_height_profile(*this, quality_factor); m_layers_editing.state = LayersEditing::Completed; m_dirty = true; } @@ -1925,7 +1921,11 @@ void GLCanvas3D::render() m_camera.debug_render(); #endif // ENABLE_CAMERA_STATISTICS +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + wxGetApp().plater()->get_mouse3d_controller().render_settings_dialog(*this); +#else wxGetApp().plater()->get_mouse3d_controller().render_settings_dialog((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height()); +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG wxGetApp().imgui()->render(); @@ -2633,8 +2633,8 @@ void GLCanvas3D::on_idle(wxIdleEvent& evt) if (m_extra_frame_requested || mouse3d_controller_applied) { m_dirty = true; - evt.RequestMore(); m_extra_frame_requested = false; + evt.RequestMore(); } else m_dirty = false; @@ -5390,7 +5390,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c // For coloring by a color_print(M600), return a parsed color. bool color_by_color_print() const { return color_print_values!=nullptr; } const size_t color_print_color_idx_by_layer_idx(const size_t layer_idx) const { - const Model::CustomGCode value(layers[layer_idx]->print_z + EPSILON, "", 0, ""); + const Model::CustomGCode value{layers[layer_idx]->print_z + EPSILON, "", 0, ""}; auto it = std::lower_bound(color_print_values->begin(), color_print_values->end(), value); return (it - color_print_values->begin()) % number_tools(); } @@ -5401,7 +5401,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c auto it = std::find_if(color_print_values->begin(), color_print_values->end(), [print_z](const Model::CustomGCode& code) - { return fabs(code.height - print_z) < EPSILON; }); + { return fabs(code.print_z - print_z) < EPSILON; }); if (it != color_print_values->end()) { const std::string& code = it->gcode; @@ -5421,7 +5421,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c } } - const Model::CustomGCode value(print_z + EPSILON, "", 0, ""); + const Model::CustomGCode value{print_z + EPSILON, "", 0, ""}; it = std::lower_bound(color_print_values->begin(), color_print_values->end(), value); while (it != color_print_values->begin()) { diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index bd31527b1d7..e07ccd7fdd5 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -185,7 +185,7 @@ private: bool m_layer_height_profile_modified; #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - mutable float m_adaptive_cusp; + mutable float m_adaptive_quality; mutable HeightProfileSmoothingParams m_smooth_params; #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE @@ -236,8 +236,8 @@ private: void accept_changes(GLCanvas3D& canvas); void reset_layer_height_profile(GLCanvas3D& canvas); #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - void adaptive_layer_height_profile(GLCanvas3D& canvas, float cusp); - void smooth_layer_height_profile(GLCanvas3D& canvas, const HeightProfileSmoothingParams& smoothing_paramsn); + void adaptive_layer_height_profile(GLCanvas3D& canvas, float quality_factor); + void smooth_layer_height_profile(GLCanvas3D& canvas, const HeightProfileSmoothingParams& smoothing_params); #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE static float get_cursor_z_relative(const GLCanvas3D& canvas); @@ -541,7 +541,7 @@ public: #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE void reset_layer_height_profile(); - void adaptive_layer_height_profile(float cusp); + void adaptive_layer_height_profile(float quality_factor); void smooth_layer_height_profile(const HeightProfileSmoothingParams& smoothing_params); #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index edb244b3475..2eb316be0fd 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -569,7 +569,7 @@ void Preview::update_view_type(bool slice_completed) { const DynamicPrintConfig& config = wxGetApp().preset_bundle->project_config; - const wxString& choice = !wxGetApp().plater()->model().custom_gcode_per_height.empty() /*&& + const wxString& choice = !wxGetApp().plater()->model().custom_gcode_per_print_z.empty() /*&& (wxGetApp().extruders_edited_cnt()==1 || !slice_completed) */? _(L("Color Print")) : config.option("wiping_volumes_matrix")->values.size() > 1 ? @@ -600,7 +600,7 @@ void Preview::create_double_slider() Bind(wxCUSTOMEVT_TICKSCHANGED, [this](wxEvent&) { Model& model = wxGetApp().plater()->model(); - model.custom_gcode_per_height = m_slider->GetTicksValues(); + model.custom_gcode_per_print_z = m_slider->GetTicksValues(); m_schedule_background_process(); update_view_type(false); @@ -646,7 +646,7 @@ void Preview::check_slider_values(std::vector& ticks_from_mo ticks_from_model.erase(std::remove_if(ticks_from_model.begin(), ticks_from_model.end(), [layers_z](Model::CustomGCode val) { - auto it = std::lower_bound(layers_z.begin(), layers_z.end(), val.height - DoubleSlider::epsilon()); + auto it = std::lower_bound(layers_z.begin(), layers_z.end(), val.print_z - DoubleSlider::epsilon()); return it == layers_z.end(); }), ticks_from_model.end()); @@ -669,7 +669,7 @@ void Preview::update_double_slider(const std::vector& layers_z, bool kee bool snap_to_min = force_sliders_full_range || m_slider->is_lower_at_min(); bool snap_to_max = force_sliders_full_range || m_slider->is_higher_at_max(); - std::vector &ticks_from_model = wxGetApp().plater()->model().custom_gcode_per_height; + std::vector &ticks_from_model = wxGetApp().plater()->model().custom_gcode_per_print_z; check_slider_values(ticks_from_model, layers_z); m_slider->SetSliderValues(layers_z); @@ -789,7 +789,7 @@ void Preview::load_print_as_fff(bool keep_z_range) colors.push_back("#808080"); // gray color for pause print or custom G-code if (!gcode_preview_data_valid) - color_print_values = wxGetApp().plater()->model().custom_gcode_per_height; + color_print_values = wxGetApp().plater()->model().custom_gcode_per_print_z; } else if (gcode_preview_data_valid || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool) ) { diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 33e526083a7..90ef017fcd9 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -254,6 +254,16 @@ bool ImGuiWrapper::begin(const wxString &name, int flags) return begin(into_u8(name), flags); } +bool ImGuiWrapper::begin(const std::string& name, bool* close, int flags) +{ + return ImGui::Begin(name.c_str(), close, (ImGuiWindowFlags)flags); +} + +bool ImGuiWrapper::begin(const wxString& name, bool* close, int flags) +{ + return begin(into_u8(name), close, flags); +} + void ImGuiWrapper::end() { ImGui::End(); diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index 7cce60367d7..5118af036d9 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -56,6 +56,8 @@ public: bool begin(const std::string &name, int flags = 0); bool begin(const wxString &name, int flags = 0); + bool begin(const std::string& name, bool* close, int flags = 0); + bool begin(const wxString& name, bool* close, int flags = 0); void end(); bool button(const wxString &label); diff --git a/src/slic3r/GUI/Mouse3DController.cpp b/src/slic3r/GUI/Mouse3DController.cpp index b3d7c0e4fe8..ad5be88d8c4 100644 --- a/src/slic3r/GUI/Mouse3DController.cpp +++ b/src/slic3r/GUI/Mouse3DController.cpp @@ -5,6 +5,9 @@ #include "GUI_App.hpp" #include "PresetBundle.hpp" #include "AppConfig.hpp" +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG +#include "GLCanvas3D.hpp" +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG #include @@ -184,7 +187,10 @@ Mouse3DController::Mouse3DController() , m_device(nullptr) , m_device_str("") , m_running(false) - , m_settings_dialog(false) + , m_show_settings_dialog(false) +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + , m_settings_dialog_closed_by_user(false) +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG { m_last_time = std::chrono::high_resolution_clock::now(); } @@ -229,8 +235,11 @@ bool Mouse3DController::apply(Camera& camera) if (!m_running && is_device_connected()) { disconnect_device(); - // hides the settings dialog if the user re-plug the device - m_settings_dialog = false; + // hides the settings dialog if the user un-plug the device + m_show_settings_dialog = false; +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + m_settings_dialog_closed_by_user = false; +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG } // check if the user plugged the device @@ -240,88 +249,144 @@ bool Mouse3DController::apply(Camera& camera) return is_device_connected() ? m_state.apply(camera) : false; } +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG +void Mouse3DController::render_settings_dialog(GLCanvas3D& canvas) const +#else void Mouse3DController::render_settings_dialog(unsigned int canvas_width, unsigned int canvas_height) const +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG { - if (!m_running || !m_settings_dialog) + if (!m_running || !m_show_settings_dialog) return; - ImGuiWrapper& imgui = *wxGetApp().imgui(); - - imgui.set_next_window_pos(0.5f * (float)canvas_width, 0.5f * (float)canvas_height, ImGuiCond_Always, 0.5f, 0.5f); - - imgui.begin(_(L("3Dconnexion settings")), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse); - - const ImVec4& color = ImGui::GetStyleColorVec4(ImGuiCol_Separator); - ImGui::PushStyleColor(ImGuiCol_Text, color); - imgui.text(_(L("Device:"))); - ImGui::PopStyleColor(); - ImGui::SameLine(); - imgui.text(m_device_str); - - ImGui::Separator(); - ImGui::PushStyleColor(ImGuiCol_Text, color); - imgui.text(_(L("Speed:"))); - ImGui::PopStyleColor(); - - float translation_scale = (float)m_state.get_translation_scale() / State::DefaultTranslationScale; - if (imgui.slider_float(_(L("Translation")) + "##1", &translation_scale, 0.5f, 2.0f, "%.1f")) - m_state.set_translation_scale(State::DefaultTranslationScale * (double)translation_scale); - - float rotation_scale = m_state.get_rotation_scale() / State::DefaultRotationScale; - if (imgui.slider_float(_(L("Rotation")) + "##1", &rotation_scale, 0.5f, 2.0f, "%.1f")) - m_state.set_rotation_scale(State::DefaultRotationScale * rotation_scale); - - ImGui::Separator(); - ImGui::PushStyleColor(ImGuiCol_Text, color); - imgui.text(_(L("Deadzone:"))); - ImGui::PopStyleColor(); - - float translation_deadzone = (float)m_state.get_translation_deadzone(); - if (imgui.slider_float(_(L("Translation")) + "##2", &translation_deadzone, 0.0f, (float)State::MaxTranslationDeadzone, "%.2f")) - m_state.set_translation_deadzone((double)translation_deadzone); - - float rotation_deadzone = m_state.get_rotation_deadzone(); - if (imgui.slider_float(_(L("Rotation")) + "##2", &rotation_deadzone, 0.0f, State::MaxRotationDeadzone, "%.2f")) - m_state.set_rotation_deadzone(rotation_deadzone); - -#if ENABLE_3DCONNEXION_DEVICES_DEBUG_OUTPUT - ImGui::Separator(); - ImGui::Separator(); - ImGui::PushStyleColor(ImGuiCol_Text, color); - imgui.text("DEBUG:"); - imgui.text("Vectors:"); - ImGui::PopStyleColor(); - Vec3f translation = m_state.get_translation().cast(); - Vec3f rotation = m_state.get_rotation(); - ImGui::InputFloat3("Translation##3", translation.data(), "%.3f", ImGuiInputTextFlags_ReadOnly); - ImGui::InputFloat3("Rotation##3", rotation.data(), "%.3f", ImGuiInputTextFlags_ReadOnly); - - ImGui::PushStyleColor(ImGuiCol_Text, color); - imgui.text("Queue size:"); - ImGui::PopStyleColor(); - - int translation_size[2] = { (int)m_state.get_translation_queue_size(), (int)m_state.get_translation_queue_max_size() }; - int rotation_size[2] = { (int)m_state.get_rotation_queue_size(), (int)m_state.get_rotation_queue_max_size() }; - int buttons_size[2] = { (int)m_state.get_buttons_queue_size(), (int)m_state.get_buttons_queue_max_size() }; - - ImGui::InputInt2("Translation##4", translation_size, ImGuiInputTextFlags_ReadOnly); - ImGui::InputInt2("Rotation##4", rotation_size, ImGuiInputTextFlags_ReadOnly); - ImGui::InputInt2("Buttons", buttons_size, ImGuiInputTextFlags_ReadOnly); - - int queue_size = (int)m_state.get_queues_max_size(); - if (ImGui::InputInt("Max size", &queue_size, 1, 1, ImGuiInputTextFlags_ReadOnly)) +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + // when the user clicks on [X] or [Close] button we need to trigger + // an extra frame to let the dialog disappear + if (m_settings_dialog_closed_by_user) { - if (queue_size > 0) - m_state.set_queues_max_size(queue_size); + m_show_settings_dialog = false; + m_settings_dialog_closed_by_user = false; + canvas.request_extra_frame(); + return; } - ImGui::Separator(); - ImGui::PushStyleColor(ImGuiCol_Text, color); - imgui.text("Camera:"); - ImGui::PopStyleColor(); - Vec3f target = wxGetApp().plater()->get_camera().get_target().cast(); - ImGui::InputFloat3("Target", target.data(), "%.3f", ImGuiInputTextFlags_ReadOnly); + Size cnv_size = canvas.get_canvas_size(); +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + + ImGuiWrapper& imgui = *wxGetApp().imgui(); +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + imgui.set_next_window_pos(0.5f * (float)cnv_size.get_width(), 0.5f * (float)cnv_size.get_height(), ImGuiCond_Always, 0.5f, 0.5f); +#else + imgui.set_next_window_pos(0.5f * (float)canvas_width, 0.5f * (float)canvas_height, ImGuiCond_Always, 0.5f, 0.5f); +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + static ImVec2 last_win_size(0.0f, 0.0f); + bool shown = true; + if (imgui.begin(_(L("3Dconnexion settings")), &shown, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse)) + { + if (shown) + { + ImVec2 win_size = ImGui::GetWindowSize(); + if ((last_win_size.x != win_size.x) || (last_win_size.y != win_size.y)) + { + // when the user clicks on [X] button, the next time the dialog is shown + // has a dummy size, so we trigger an extra frame to let it have the correct size + last_win_size = win_size; + canvas.request_extra_frame(); + } +#else + imgui.begin(_(L("3Dconnexion settings")), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse); +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + + const ImVec4& color = ImGui::GetStyleColorVec4(ImGuiCol_Separator); + ImGui::PushStyleColor(ImGuiCol_Text, color); + imgui.text(_(L("Device:"))); + ImGui::PopStyleColor(); + ImGui::SameLine(); + imgui.text(m_device_str); + + ImGui::Separator(); + ImGui::PushStyleColor(ImGuiCol_Text, color); + imgui.text(_(L("Speed:"))); + ImGui::PopStyleColor(); + + float translation_scale = (float)m_state.get_translation_scale() / State::DefaultTranslationScale; + if (imgui.slider_float(_(L("Translation")) + "##1", &translation_scale, 0.5f, 2.0f, "%.1f")) + m_state.set_translation_scale(State::DefaultTranslationScale * (double)translation_scale); + + float rotation_scale = m_state.get_rotation_scale() / State::DefaultRotationScale; + if (imgui.slider_float(_(L("Rotation")) + "##1", &rotation_scale, 0.5f, 2.0f, "%.1f")) + m_state.set_rotation_scale(State::DefaultRotationScale * rotation_scale); + + ImGui::Separator(); + ImGui::PushStyleColor(ImGuiCol_Text, color); + imgui.text(_(L("Deadzone:"))); + ImGui::PopStyleColor(); + + float translation_deadzone = (float)m_state.get_translation_deadzone(); + if (imgui.slider_float(_(L("Translation")) + "##2", &translation_deadzone, 0.0f, (float)State::MaxTranslationDeadzone, "%.2f")) + m_state.set_translation_deadzone((double)translation_deadzone); + + float rotation_deadzone = m_state.get_rotation_deadzone(); + if (imgui.slider_float(_(L("Rotation")) + "##2", &rotation_deadzone, 0.0f, State::MaxRotationDeadzone, "%.2f")) + m_state.set_rotation_deadzone(rotation_deadzone); + +#if ENABLE_3DCONNEXION_DEVICES_DEBUG_OUTPUT + ImGui::Separator(); + ImGui::Separator(); + ImGui::PushStyleColor(ImGuiCol_Text, color); + imgui.text("DEBUG:"); + imgui.text("Vectors:"); + ImGui::PopStyleColor(); + Vec3f translation = m_state.get_translation().cast(); + Vec3f rotation = m_state.get_rotation(); + ImGui::InputFloat3("Translation##3", translation.data(), "%.3f", ImGuiInputTextFlags_ReadOnly); + ImGui::InputFloat3("Rotation##3", rotation.data(), "%.3f", ImGuiInputTextFlags_ReadOnly); + + ImGui::PushStyleColor(ImGuiCol_Text, color); + imgui.text("Queue size:"); + ImGui::PopStyleColor(); + + int translation_size[2] = { (int)m_state.get_translation_queue_size(), (int)m_state.get_translation_queue_max_size() }; + int rotation_size[2] = { (int)m_state.get_rotation_queue_size(), (int)m_state.get_rotation_queue_max_size() }; + int buttons_size[2] = { (int)m_state.get_buttons_queue_size(), (int)m_state.get_buttons_queue_max_size() }; + + ImGui::InputInt2("Translation##4", translation_size, ImGuiInputTextFlags_ReadOnly); + ImGui::InputInt2("Rotation##4", rotation_size, ImGuiInputTextFlags_ReadOnly); + ImGui::InputInt2("Buttons", buttons_size, ImGuiInputTextFlags_ReadOnly); + + int queue_size = (int)m_state.get_queues_max_size(); + if (ImGui::InputInt("Max size", &queue_size, 1, 1, ImGuiInputTextFlags_ReadOnly)) + { + if (queue_size > 0) + m_state.set_queues_max_size(queue_size); + } + + ImGui::Separator(); + ImGui::PushStyleColor(ImGuiCol_Text, color); + imgui.text("Camera:"); + ImGui::PopStyleColor(); + Vec3f target = wxGetApp().plater()->get_camera().get_target().cast(); + ImGui::InputFloat3("Target", target.data(), "%.3f", ImGuiInputTextFlags_ReadOnly); #endif // ENABLE_3DCONNEXION_DEVICES_DEBUG_OUTPUT +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + + ImGui::Separator(); + if (imgui.button(_(L("Close")))) + { + // the user clicked on the [Close] button + m_settings_dialog_closed_by_user = true; + canvas.set_as_dirty(); + } + } + else + { + // the user clicked on the [X] button + m_settings_dialog_closed_by_user = true; + canvas.set_as_dirty(); + } + } +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG imgui.end(); } diff --git a/src/slic3r/GUI/Mouse3DController.hpp b/src/slic3r/GUI/Mouse3DController.hpp index cc03d4a24ce..543c44e775e 100644 --- a/src/slic3r/GUI/Mouse3DController.hpp +++ b/src/slic3r/GUI/Mouse3DController.hpp @@ -18,6 +18,9 @@ namespace Slic3r { namespace GUI { struct Camera; +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG +class GLCanvas3D; +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG class Mouse3DController { @@ -130,7 +133,13 @@ class Mouse3DController hid_device* m_device; std::string m_device_str; bool m_running; - bool m_settings_dialog; +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + mutable bool m_show_settings_dialog; + // set to true when ther user closes the dialog by clicking on [X] or [Close] buttons + mutable bool m_settings_dialog_closed_by_user; +#else + bool m_show_settings_dialog; +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG std::chrono::time_point m_last_time; public: @@ -146,9 +155,13 @@ public: bool apply(Camera& camera); - bool is_settings_dialog_shown() const { return m_settings_dialog; } - void show_settings_dialog(bool show) { m_settings_dialog = show && is_running(); } + bool is_settings_dialog_shown() const { return m_show_settings_dialog; } + void show_settings_dialog(bool show) { m_show_settings_dialog = show && is_running(); } +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + void render_settings_dialog(GLCanvas3D& canvas) const; +#else void render_settings_dialog(unsigned int canvas_width, unsigned int canvas_height) const; +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG private: bool connect_device(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 29b83bebabb..79ebd28505d 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2370,7 +2370,7 @@ std::vector Plater::priv::load_files(const std::vector& input_ config += std::move(config_loaded); } - this->model.custom_gcode_per_height = model.custom_gcode_per_height; + this->model.custom_gcode_per_print_z = model.custom_gcode_per_print_z; } if (load_config) @@ -2789,7 +2789,7 @@ void Plater::priv::reset() // The hiding of the slicing results, if shown, is not taken care by the background process, so we do it here this->sidebar->show_sliced_info_sizer(false); - model.custom_gcode_per_height.clear(); + model.custom_gcode_per_print_z.clear(); } void Plater::priv::mirror(Axis axis) @@ -3282,22 +3282,30 @@ void Plater::priv::reload_from_disk() input_paths.push_back(sel_filename_path); missing_input_paths.pop_back(); - std::string sel_path = fs::path(sel_filename_path).remove_filename().string(); + fs::path sel_path = fs::path(sel_filename_path).remove_filename().string(); std::vector::iterator it = missing_input_paths.begin(); while (it != missing_input_paths.end()) { // try to use the path of the selected file with all remaining missing files - std::string repathed_filename = sel_path + "/" + it->filename().string(); + fs::path repathed_filename = sel_path; + repathed_filename /= it->filename(); if (fs::exists(repathed_filename)) { - input_paths.push_back(repathed_filename); + input_paths.push_back(repathed_filename.string()); it = missing_input_paths.erase(it); } else ++it; } } + else + { + wxString message = _(L("It is not allowed to change the file to reload")) + " (" + from_u8(fs::path(search).filename().string())+ ").\n" + _(L("Do you want to retry")) + " ?"; + wxMessageDialog dlg(q, message, wxMessageBoxCaptionStr, wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION); + if (dlg.ShowModal() != wxID_YES) + return; + } } #endif // ENABLE_RELOAD_FROM_DISK_MISSING_SELECTION @@ -5042,6 +5050,7 @@ void Plater::drive_ejected_callback() { if (RemovableDriveManager::get_instance().get_did_eject()) { + RemovableDriveManager::get_instance().set_did_eject(false); wxString message = "Unmounting succesesful. The device " + RemovableDriveManager::get_instance().get_last_save_name() + "(" + RemovableDriveManager::get_instance().get_last_save_path() + ")" + " can now be safely removed from the computer."; wxMessageBox(message); } @@ -5260,6 +5269,7 @@ const DynamicPrintConfig* Plater::get_plater_config() const return p->config; } +// Get vector of extruder colors considering filament color, if extruder color is undefined. std::vector Plater::get_extruder_colors_from_plater_config() const { const Slic3r::DynamicPrintConfig* config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; @@ -5279,13 +5289,17 @@ std::vector Plater::get_extruder_colors_from_plater_config() const return extruder_colors; } +/* Get vector of colors used for rendering of a Preview scene in "Color print" mode + * It consists of extruder colors and colors, saved in model.custom_gcode_per_print_z + */ std::vector Plater::get_colors_for_color_print() const { std::vector colors = get_extruder_colors_from_plater_config(); + colors.reserve(colors.size() + p->model.custom_gcode_per_print_z.size()); - for (const Model::CustomGCode& code : p->model.custom_gcode_per_height) + for (const Model::CustomGCode& code : p->model.custom_gcode_per_print_z) if (code.gcode == ColorChangeCode) - colors.push_back(code.color); + colors.emplace_back(code.color); return colors; } diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp index 9b8eaa8ec06..dbfd446b11c 100644 --- a/src/slic3r/GUI/PresetBundle.cpp +++ b/src/slic3r/GUI/PresetBundle.cpp @@ -29,6 +29,7 @@ #include "libslic3r/libslic3r.h" #include "libslic3r/Utils.hpp" +#include "GUI_App.hpp" // Store the print/filament/printer presets into a "presets" subdirectory of the Slic3rPE config dir. // This breaks compatibility with the upstream Slic3r if the --datadir is used to switch between the two versions. @@ -868,6 +869,9 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool } // 4) Load the project config values (the per extruder wipe matrix etc). this->project_config.apply_only(config, s_project_options); + + update_custom_gcode_per_print_z_from_config(GUI::wxGetApp().plater()->model().custom_gcode_per_print_z, &this->project_config); + break; } case ptSLA: diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 6e13a59b5ce..7a2464351c9 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -505,6 +505,7 @@ void RemovableDriveManager::erase_callbacks() } void RemovableDriveManager::set_last_save_path(const std::string& path) { + m_last_save_path_verified = false; m_last_save_path = path; } void RemovableDriveManager::verify_last_save_path() @@ -571,4 +572,8 @@ bool RemovableDriveManager::get_did_eject() { return m_did_eject; } +void RemovableDriveManager::set_did_eject(const bool b) +{ + m_did_eject = b; +} }}//namespace Slicer::Gui diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 1b337338e98..ea4584feee4 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -56,6 +56,7 @@ public: void set_is_writing(const bool b); bool get_is_writing(); bool get_did_eject(); + void set_did_eject(const bool b); std::string get_drive_name(const std::string& path); private: RemovableDriveManager(); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index c359f76624a..6721e8a33ec 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -2538,7 +2538,7 @@ std::vector DoubleSlider::GetTicksValues() const for (const TICK_CODE& tick : m_ticks_) { if (tick.tick > val_size) break; - values.push_back(t_custom_code(m_values[tick.tick], tick.gcode, tick.extruder, tick.color)); + values.emplace_back(t_custom_code{m_values[tick.tick], tick.gcode, tick.extruder, tick.color}); } return values; @@ -2553,12 +2553,12 @@ void DoubleSlider::SetTicksValues(const std::vector& heights) m_ticks_.clear(); for (auto h : heights) { - auto it = std::lower_bound(m_values.begin(), m_values.end(), h.height - epsilon()); + auto it = std::lower_bound(m_values.begin(), m_values.end(), h.print_z - epsilon()); if (it == m_values.end()) continue; - m_ticks_.insert(TICK_CODE(it-m_values.begin(), h.gcode, h.extruder, h.color)); + m_ticks_.emplace(TICK_CODE{int(it-m_values.begin()), h.gcode, h.extruder, h.color}); } if (!was_empty && m_ticks_.empty()) @@ -2642,7 +2642,7 @@ void DoubleSlider::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoin return; wxBitmap* icon = m_is_action_icon_focesed ? &m_bmp_add_tick_off.bmp() : &m_bmp_add_tick_on.bmp(); - if (m_ticks_.find(tick) != m_ticks_.end()) + if (m_ticks_.find(TICK_CODE{tick}) != m_ticks_.end()) icon = m_is_action_icon_focesed ? &m_bmp_del_tick_off.bmp() : &m_bmp_del_tick_on.bmp(); wxCoord x_draw, y_draw; @@ -3081,7 +3081,7 @@ wxString DoubleSlider::get_tooltip(IconFocus icon_focus) else if (m_is_action_icon_focesed) { const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; - const auto tick_code_it = m_ticks_.find(tick); + const auto tick_code_it = m_ticks_.find(TICK_CODE{tick}); tooltip = tick_code_it == m_ticks_.end() ? (m_state == msSingleExtruder ? _(L("For add color change use left mouse button click")) : _(L("For add change extruder use left mouse button click"))) + "\n" + @@ -3240,13 +3240,13 @@ void DoubleSlider::action_tick(const TicksAction action) const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; - const auto it = m_ticks_.find(tick); + const auto it = m_ticks_.find(TICK_CODE{tick}); if (it != m_ticks_.end()) // erase this tick { if (action == taAdd) return; - m_ticks_.erase(TICK_CODE(tick)); + m_ticks_.erase(TICK_CODE{tick}); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); Refresh(); @@ -3350,7 +3350,7 @@ void DoubleSlider::OnRightDown(wxMouseEvent& event) { const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; // if on this Z doesn't exist tick - auto it = m_ticks_.find(tick); + auto it = m_ticks_.find(TICK_CODE{ tick }); if (it == m_ticks_.end()) { // show context menu on OnRightUp() @@ -3387,7 +3387,7 @@ int DoubleSlider::get_extruder_for_tick(int tick) if (m_ticks_.empty()) return 0; - auto it = m_ticks_.lower_bound(tick); + auto it = m_ticks_.lower_bound(TICK_CODE{tick}); while (it != m_ticks_.begin()) { --it; if(it->gcode == Slic3r::ExtruderChangeCode) @@ -3454,7 +3454,7 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event) else if (m_show_edit_menu) { wxMenu menu; - std::set::iterator it = m_ticks_.find(m_selection == ssLower ? m_lower_value : m_higher_value); + std::set::iterator it = m_ticks_.find(TICK_CODE{ m_selection == ssLower ? m_lower_value : m_higher_value }); const bool is_color_change = it->gcode == Slic3r::ColorChangeCode; append_menu_item(&menu, wxID_ANY, it->gcode == Slic3r::ColorChangeCode ? _(L("Edit color")) : @@ -3526,7 +3526,7 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) { const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; // if on this Z doesn't exist tick - auto it = m_ticks_.find(tick); + auto it = m_ticks_.find(TICK_CODE{ tick }); if (it == m_ticks_.end()) { std::string color = ""; @@ -3535,7 +3535,7 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) std::vector colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); if (m_state == msSingleExtruder && !m_ticks_.empty()) { - auto before_tick_it = std::lower_bound(m_ticks_.begin(), m_ticks_.end(), tick); + auto before_tick_it = std::lower_bound(m_ticks_.begin(), m_ticks_.end(), TICK_CODE{ tick }); while (before_tick_it != m_ticks_.begin()) { --before_tick_it; if (before_tick_it->gcode == Slic3r::ColorChangeCode) { @@ -3580,7 +3580,7 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) extruder = get_extruder_for_tick(m_selection == ssLower ? m_lower_value : m_higher_value); } - m_ticks_.insert(TICK_CODE(tick, code, extruder, color)); + m_ticks_.emplace(TICK_CODE{tick, code, extruder, color}); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); Refresh(); @@ -3592,7 +3592,7 @@ void DoubleSlider::edit_tick() { const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; // if on this Z exists tick - std::set::iterator it = m_ticks_.find(tick); + std::set::iterator it = m_ticks_.find(TICK_CODE{ tick }); if (it != m_ticks_.end()) { std::string edited_value; @@ -3619,7 +3619,7 @@ void DoubleSlider::edit_tick() } m_ticks_.erase(it); - m_ticks_.insert(changed_tick); + m_ticks_.emplace(changed_tick); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); } @@ -3632,9 +3632,9 @@ void DoubleSlider::change_extruder(int extruder) std::vector colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); // if on this Y doesn't exist tick - if (m_ticks_.find(tick) == m_ticks_.end()) + if (m_ticks_.find(TICK_CODE{tick}) == m_ticks_.end()) { - m_ticks_.insert(TICK_CODE(tick, Slic3r::ExtruderChangeCode, extruder, extruder == 0 ? "" : colors[extruder-1])); + m_ticks_.emplace(TICK_CODE{tick, Slic3r::ExtruderChangeCode, extruder, extruder == 0 ? "" : colors[extruder-1]}); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); Refresh(); @@ -3672,7 +3672,7 @@ void DoubleSlider::edit_extruder_sequence() while (tick <= m_max_value) { int cur_extruder = m_extruders_sequence.extruders[extruder]; - m_ticks_.insert(TICK_CODE(tick, Slic3r::ExtruderChangeCode, cur_extruder + 1, colors[cur_extruder])); + m_ticks_.emplace(TICK_CODE{tick, Slic3r::ExtruderChangeCode, cur_extruder + 1, colors[cur_extruder]}); extruder++; if (extruder == extr_cnt) @@ -3680,12 +3680,12 @@ void DoubleSlider::edit_extruder_sequence() if (m_extruders_sequence.is_mm_intervals) { value += m_extruders_sequence.interval_by_mm; - auto it = std::lower_bound(m_values.begin(), m_values.end(), value - epsilon()); + auto val_it = std::lower_bound(m_values.begin(), m_values.end(), value - epsilon()); - if (it == m_values.end()) + if (val_it == m_values.end()) break; - tick = it - m_values.begin(); + tick = val_it - m_values.begin(); } else tick += m_extruders_sequence.interval_by_layers; diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 26e334def4a..ebed49efe6d 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -17,6 +17,7 @@ #include #include #include "libslic3r/Model.hpp" +#include "libslic3r/GCodeWriter.hpp" namespace Slic3r { enum class ModelVolumeType : int; @@ -961,24 +962,12 @@ private: struct TICK_CODE { - TICK_CODE(int tick):tick(tick), gcode(Slic3r::ColorChangeCode), extruder(0), color("") {} - TICK_CODE(int tick, const std::string& code) : - tick(tick), gcode(code), extruder(0) {} - TICK_CODE(int tick, int extruder) : - tick(tick), gcode(Slic3r::ColorChangeCode), extruder(extruder) {} - TICK_CODE(int tick, const std::string& code, int extruder, const std::string& color) : - tick(tick), gcode(code), extruder(extruder), color(color) {} - bool operator<(const TICK_CODE& other) const { return other.tick > this->tick; } bool operator>(const TICK_CODE& other) const { return other.tick < this->tick; } - TICK_CODE operator=(const TICK_CODE& other) const { - TICK_CODE ret_val(other.tick, other.gcode, other.extruder, other.color); - return ret_val; - } int tick; - std::string gcode; - int extruder; + std::string gcode = Slic3r::ColorChangeCode; + int extruder = 0; std::string color; }; diff --git a/version.inc b/version.inc index 0a62ff6f358..c96a304ab3e 100644 --- a/version.inc +++ b/version.inc @@ -3,7 +3,7 @@ set(SLIC3R_APP_NAME "PrusaSlicer") set(SLIC3R_APP_KEY "PrusaSlicer") -set(SLIC3R_VERSION "2.1.0") +set(SLIC3R_VERSION "2.2.0-alpha0") set(SLIC3R_BUILD_ID "PrusaSlicer-${SLIC3R_VERSION}+UNKNOWN") -set(SLIC3R_RC_VERSION "2,1,0,0") -set(SLIC3R_RC_VERSION_DOTS "2.1.0.0") +set(SLIC3R_RC_VERSION "2,2,0,0") +set(SLIC3R_RC_VERSION_DOTS "2.2.0.0")