From ef12f355998ae929142afd164c524792c6a86d36 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 60f4edf478..67d8bd8cf4 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 0000000000..44d4181d1b --- /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 0000000000..cab58fee6c --- /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 4822b577d2af2c37c56ae0a012b59c3177ed7502 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 6dcbc60b71..bb196d3fde 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 44d4181d1b..ae718b7d3a 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 cab58fee6c..c503fdf187 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 fdf159af42919a7d07288559732e93641b7e2588 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 67d8bd8cf4..320f337515 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 ae718b7d3a..53515ccdcb 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 c503fdf187..8270c0f0fb 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 97a9f245f96617dfd1fb74c1262911abf1b68108 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 320f337515..16f0459664 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 789271581e..bbfa9d9328 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 53515ccdcb..776334bf22 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 8270c0f0fb..3de9d72cee 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 1cd06e32675eea22253312629d2d1ef0b75850d4 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 776334bf22..2d1f4ba6f2 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 4337b65f52e3ed761481cfafbd5c0aeb2e034d42 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 a74c6b0c06..35c11f0211 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 2d1f4ba6f2..235e1ccbe8 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 3de9d72cee..c83b8033c9 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 b7a5020196ecb42179825eb3504604f2e99e802d 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 235e1ccbe8..a1a5d7dd92 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 c83b8033c9..9f3ebf326b 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 7301b4f7dd59138e8a44f1cc68996083db0dda9c 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 35c11f0211..10eb4ab59b 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 bbfa9d9328..74b2d12391 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 a1a5d7dd92..777085165d 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 9f3ebf326b..f3abc42073 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 82baaf291eaaaeeea061003602504c8c7f4ee7ea 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 777085165d..4368d06b64 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 f3abc42073..43e47a0867 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 0eb8cb3fa159028f9ddfe3fd2428a864218b5782 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 10eb4ab59b..c36c2748dd 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 4368d06b64..ec730692fa 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 43e47a0867..b465b1c1b8 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 55409b0e96e804c4733956f74a23ef70a1c3945b 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 ec730692fa..9b3020e79e 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 14fdf429ea3bb30ef9f1622912cab81efe696785 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 9b3020e79e..bdc1727403 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 79cdb0ab07e8e1c62b5583384e33561e9d93aa76 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 bdc1727403..99520b8429 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 fd7d75028a28f78b8d5c16c8d3b8a5269f7680e3 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 99520b8429..e1ab1626c5 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 0b015b0864911f45aaa9e6feb2c4c630575746c3 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 e1ab1626c5..3ff5735f91 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 1c9dddeb2b923c2444def337ab0f7f0be34a099d 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 3ff5735f91..7216763eec 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 9a301ac98df7ffecfa1e86dbc66d2f1259a9a3dd 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 7216763eec..c859a5d872 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 1f6d2c87b85855e4998e7770a75499e3665652c9 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 c859a5d872..3d77606c81 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 0a4b2331a15c93cd503117b7110d3ed5c4013d4d 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 3d77606c81..0665e57dc2 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 18be3ffb5f6db881353d12331c2022f304220be9 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 0665e57dc2..a655425fc4 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 5f54856be0ae9dbde03595101e040f9fd45afab7 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 c36c2748dd..37753a0dea 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 5d967cb6c0..d1ce50f41f 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 a655425fc4..146bebc119 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 c65a7fe625..be5ae5968e 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 822ffa6c86076cd4f49731c09b84b4248104976f 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 37753a0dea..ed5371e669 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 146bebc119..e94ea6918a 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 be5ae5968e..906667244b 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 0f18e7e7ecb81e896f19bc9a5704b133225198bf 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 e94ea6918a..6581d53614 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 906667244b..741b4424ab 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 118354ecf43e366f6670b0dc6c83f6882f02b472 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 6581d53614..1fbc33fc57 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 741b4424ab..8d9e65c47e 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 87fff4626e4a584abffb98da52dd62577cd997ee 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 ed5371e669..90e6cd4bdb 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 1fbc33fc57..5daa9eb261 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 8d9e65c47e..210d89477b 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 0d2a2d2b20e128b6de3ca65b7140a26badeb23ba 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 03413f9337..6a14a1b3f3 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 5daa9eb261..166728e68b 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 210d89477b..501c16b71a 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 0000000000..a1358625fc --- /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 8810a9aa31d07a63a1de6af0fefeb6ed6cb1f183 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 90e6cd4bdb..1b2fe919a2 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 fdc493f6fd1d76209e5109f55d47aa9619867597 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 6a14a1b3f3..9d51f6219c 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 501c16b71a..04bbe48b5d 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 0000000000..8f783c2d2a --- /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 a1358625fc..e4e324654e 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 40a83e67dd11f2cb66beae511159aa42c9a44fad 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 166728e68b..8145c90760 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 04bbe48b5d..c4f55029b7 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 e4e324654e..99abd73860 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 3b6daf64c7b22a2ba3ffa7dda89bc22aa36fd0a1 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 8145c90760..50e2b6359c 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 c4f55029b7..7109bbd070 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 8f783c2d2a..4a5fa2515e 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 99abd73860..7e8b56c59b 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 d2a440c79440b63cda1c62e8b2f423b2e616bde4 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 50e2b6359c..763113ea2c 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 7109bbd070..202680328e 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 4a5fa2515e..2999415454 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 7e8b56c59b..25fa6da091 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 027b9f508285b3ab7e9783f4c165aa99bee4f886 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 763113ea2c..c5dca1bd55 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 37b6d9e8adb5964d7933bcc999302a0a1301f6b7 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 d1ce50f41f..b50f6f150d 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 5c36dbf5e0..af4b989c42 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 cd1d49b015e7f90c375c44bc6ef15e11507dfdaf 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 202680328e..cbf6f53aac 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 25fa6da091..269a2255b0 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 be09c91a1d1984e74d4ec0133314200fe100b1cf 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 0000000000..fe8de635db --- /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 bcfc333fb108f87e62f961f403ede08cebc124a5 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 c5dca1bd55..164b6e38aa 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 cbf6f53aac..a5027a5adf 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 269a2255b0..d32b7b278e 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 975642e3e055297bd178196c16a69eaf58cb75bb 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 b50f6f150d..e94e0a4e63 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 af4b989c42..a247f82922 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 164b6e38aa..1a964f889d 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 a5027a5adf..f412940010 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 4a7f50ad669a3b71cf152b61a751cc088151578e 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 1b2fe919a2..fc25b4f295 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 e94e0a4e63..905d56e900 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 1a964f889d..49bf59e11f 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 f412940010..49df414827 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 d32b7b278e..7a1108541a 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 6dddc1cc6bcb1b7376b2af15bd271f2984190377 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 905d56e900..0300670e48 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 38c69f16f04cd051d66175e39514c4e0873de8e5 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 fc25b4f295..8e450f4972 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 49bf59e11f..284c224fbd 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 49df414827..9eea355f79 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 7a1108541a..45bd21bcfa 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 f057077826b7499a54f7b21ef198a370446b53ad 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 fc25b4f295..8e450f4972 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 49bf59e11f..dc8469d9a2 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 a03ce255d6ad5b84b62f1bb9afa5b34e3e13617b 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 afe5ee7393..ab2dd10eb2 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 e2048775f6bc1f729df39843d7683ad33f457c1b 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 0300670e48..a0e453abc3 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 59fa78373b1a0cd199bfac3ddc513235ca33e59f 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 8e450f4972..258e338719 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 ab2dd10eb2..d5f2244095 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 258e338719..bdaf8f8a79 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 a0e453abc3..74a26c4002 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 d5f2244095..7ab34204bc 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 74a26c4002..3ecb174ce9 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 7ab34204bc..cd360b580f 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 9eea355f79..b4fc71e265 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 e1d9de3ca425cedaa239106dd67d0055751d2e30 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 3ecb174ce9..417afa0a96 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 ff58fa99f41f315e1f03ee330ea7b528e5c65f55 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 cd360b580f..02681b7daf 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 b4fc71e265..ac1645df7b 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 8895e944cf2deca3b894415ba05fe281af4a7456 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 417afa0a96..0dc09d9d81 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 e5fcb587e2bbff1313da989924792c44cd4f4a92 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 417afa0a96..814bcde0cf 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 8493138971..735e704ee8 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 7841b62fee..951f7ea8f4 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 8b4732e811fcca736c6e8a78b1d03c441d30ea2c 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 d33d945efb..4f3272e264 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 0000000000..44d4181d1b --- /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 0000000000..cab58fee6c --- /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 04ef585124bfc65c745ccbeada994dc7c6ac7bb0 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 bcddcfe069..2d7b99b73d 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 44d4181d1b..ae718b7d3a 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 cab58fee6c..c503fdf187 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 b8b4b1dd42953ceedf7a5a4e36433a7d01e2d28a 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 4f3272e264..26ca07082d 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 ae718b7d3a..53515ccdcb 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 c503fdf187..8270c0f0fb 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 852d8ad5ccac07176ad156d802c637dd1d828a20 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 26ca07082d..7055822513 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 c8267331d3..efe0ab7b31 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 53515ccdcb..776334bf22 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 8270c0f0fb..3de9d72cee 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 6e9a37e81bd4e91f59a68c3a2104aa0c7cfa3cab 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 776334bf22..2d1f4ba6f2 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 1790c795fbdc4a2cca1006bd0e4f686f0e77ca2e 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 e02dd5f6e7..3d09e3573b 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 2d1f4ba6f2..235e1ccbe8 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 3de9d72cee..c83b8033c9 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 649f3a2c3ea783648bdf839028debbac76bde9be 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 235e1ccbe8..a1a5d7dd92 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 c83b8033c9..9f3ebf326b 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 735308b794bb84d0a34c4e67de14f9836168abc3 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 3d09e3573b..e33fc0d2e5 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 efe0ab7b31..3e3827926f 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 a1a5d7dd92..777085165d 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 9f3ebf326b..f3abc42073 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 17b146c0a36937287beb519040a7b4446c00935a 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 777085165d..4368d06b64 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 f3abc42073..43e47a0867 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 5db80edcd3989e5210513a2673f6d6e0f5977732 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 e33fc0d2e5..e6c92cd0a8 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 4368d06b64..ec730692fa 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 43e47a0867..b465b1c1b8 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 9b991953e5008e053ce8dd0adf8894bf81a0cd82 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 ec730692fa..9b3020e79e 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 f651c7b7ec789d4f354e2103a4641f4734f830c7 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 9b3020e79e..bdc1727403 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 73ba196e787c4720b778e6021c5574391fea747e 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 bdc1727403..99520b8429 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 4e3eb89d315a98f1d086cd066c1ea63d23aab724 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 99520b8429..e1ab1626c5 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 f82bf0d49576bff865d307316a5581a5a6c42893 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 e1ab1626c5..3ff5735f91 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 d2ef01990b93c3baf5e935e8951889a8cd53848d 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 3ff5735f91..7216763eec 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 3d036d363b164ea2d84016f087e3247adbb29eb6 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 7216763eec..c859a5d872 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 f81faaf9e956f4dc134e99929a8d4291aa4b05d5 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 c859a5d872..3d77606c81 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 a6e10e8fa27b654718e622ba66933a6e4586ad51 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 3d77606c81..0665e57dc2 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 1c8ca1aec15d70a4b1ed172a245b028e26948b44 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 0665e57dc2..a655425fc4 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 63ee4e3a2f766ad3856244c42e4f28ff5828b240 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 e6c92cd0a8..0d608876eb 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 3e3827926f..b8b2f45e8b 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 a655425fc4..146bebc119 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 c65a7fe625..be5ae5968e 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 66f203379cb7437a69e04cb6d88d24ee40a014df 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 0d608876eb..28812dcf43 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 146bebc119..e94ea6918a 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 be5ae5968e..906667244b 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 6396ec571a0c70367c917efaf2b662b300a2723c 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 e94ea6918a..6581d53614 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 906667244b..741b4424ab 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 b386eb45dccc3d951940ed32e6cb6ff945dfa773 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 6581d53614..1fbc33fc57 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 741b4424ab..8d9e65c47e 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 8f069e2d473ddb98d4adb7e3d094e2c0fae5b73c 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 28812dcf43..72c84ba799 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 1fbc33fc57..5daa9eb261 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 8d9e65c47e..210d89477b 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 91c358fe237e3bd0232c661ca99b813472cb2719 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 2d7b99b73d..246f1365b0 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 5daa9eb261..166728e68b 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 210d89477b..501c16b71a 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 0000000000..a1358625fc --- /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 0861b2ec591161355890779058b91a23cb7580c1 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 72c84ba799..e13701f61d 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 e0a12342da33ea2e79b06777c5579294094353ed 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 246f1365b0..a06a8cf1d1 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 501c16b71a..04bbe48b5d 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 0000000000..8f783c2d2a --- /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 a1358625fc..e4e324654e 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 c3653589f6cec74a9a4241c9de55e28c178cd6d6 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 166728e68b..8145c90760 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 04bbe48b5d..c4f55029b7 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 e4e324654e..99abd73860 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 c37128ad638f99c5b090cce5427e12bcbf81af94 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 8145c90760..50e2b6359c 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 c4f55029b7..7109bbd070 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 8f783c2d2a..4a5fa2515e 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 99abd73860..7e8b56c59b 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 a259058845e50d635883e16cf86d0988c31a76bd 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 50e2b6359c..763113ea2c 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 7109bbd070..202680328e 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 4a5fa2515e..2999415454 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 7e8b56c59b..25fa6da091 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 c47fda39f1fb47fa77ff5e575bc4123597fb4c1a 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 b8b2f45e8b..7b5cef4ca4 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 33140c4f5d..528d652971 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 95ff384e47d3d4020af1a0468616fd2f167f0d76 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 763113ea2c..c5dca1bd55 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 9e4f470f98037860346d7902b84b0407099dba1d 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 202680328e..cbf6f53aac 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 25fa6da091..269a2255b0 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 44b1a9cf7fe8b277e7ba61f50611feaeb46f922e 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 c5dca1bd55..164b6e38aa 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 cbf6f53aac..a5027a5adf 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 269a2255b0..d32b7b278e 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 01f1bed0605662e8520f24c5db8c8bdac5f7eb4e 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 0000000000..fe8de635db --- /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 f5e3750d233d1f9687fa9c906b39150df1eca609 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 7b5cef4ca4..ed60066e54 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 528d652971..d9a9af3763 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 164b6e38aa..1a964f889d 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 a5027a5adf..f412940010 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 8f0eef8f36683a17b1749f52784efc7bbd2f576d 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 e13701f61d..786a5901e5 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 ed60066e54..7edf657be4 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 1a964f889d..49bf59e11f 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 f412940010..49df414827 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 d32b7b278e..7a1108541a 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 a01eec34f9f1cc1196187b6dba7a47afebd9e2bb 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 7edf657be4..8a96ac4d42 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 b267e986fb67282017f6f391c7cab9b915c4df0f 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 786a5901e5..b83ecbedc8 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 49bf59e11f..dc8469d9a2 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 12cb9a81439e51127f2517d3767fca8ce2ed1052 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 dc8469d9a2..afe5ee7393 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 49df414827..9eea355f79 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 7a1108541a..45bd21bcfa 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 68125b12a740144461ff408b0533fe412e70287c 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 8a96ac4d42..d578649110 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 19789d78c21a86075d0f7f09473ba5e18603fb99 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 afe5ee7393..ab2dd10eb2 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 1d25201a12cce36b55ad6268ac491d4fcbda5a33 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 b83ecbedc8..c9ed88f84a 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 ab2dd10eb2..d5f2244095 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 c9ed88f84a..f601cd4bc7 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 d578649110..eb5f6d4850 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 d5f2244095..7ab34204bc 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 eb5f6d4850..cefe31e90b 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 7ab34204bc..cd360b580f 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 9eea355f79..b4fc71e265 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 5a9ec0d0743ccc51e0edf476cd784f5cf119692f 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 cefe31e90b..910de4722f 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 8e1292f353468ad820315a773bdcf18d9cbd7e27 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 cd360b580f..02681b7daf 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 b4fc71e265..ac1645df7b 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 acab61fa5430ae3c983e9c08e5ff1e7159319af1 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 910de4722f..52255d1763 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 f3ecf55d3840634941a0f9b053516d20a183a6a5 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 7055822513..f24bde2426 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 02681b7daf..ba5ab50727 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 ac1645df7b..a5abde72d0 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 4bf8a0ef24ea0a2212d6c8cf2661d2617c4af773 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 ba5ab50727..e613320454 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 a5abde72d0..157f670b31 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 72f1adbb443a37cd2ffc9f005e63549f032085c0 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 f24bde2426..9f294a3b60 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 e613320454..30f6c9b290 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 157f670b31..c001644460 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 1ec7fc23e24b7d981b513d52a039201f2cac506f 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 9f294a3b60..e27fa1be65 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 52255d1763..aff162401f 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 30f6c9b290..02681b7daf 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 c001644460..1e5d240f09 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 9c79c7f644d0e2155cb7bd1c50bcc4b7b6e03d47 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 e27fa1be65..d33d945efb 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 aff162401f..52255d1763 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 02681b7daf..77a387aaf5 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 1e5d240f09..fa42f5e735 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 6de41c6147ec921f0b06e1769d70e94898b31a2a 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 52255d1763..02f8ace078 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 2df903640bc4c5e9906aef0bf7a6b9beb3acc169 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 02f8ace078..cff3164e8e 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 302a5e5210..e64a3fce59 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 7841b62fee..951f7ea8f4 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 7d0d70534b70f12de81159fad7d04d93aef5cb26 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 72d01b41d8..fa18bd5ea0 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 e64a3fce59..c359f76624 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 951f7ea8f4..26e334def4 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 5a26be1150314f2abd04229e3d69991436a679da 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 72d01b41d8..f1bdbb23ef 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 1c2a29b0ba..535d62f83f 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 0db9815467d45812f6d727d60ba637613050d964 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 ce29120abc..63521815df 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 535d62f83f..5af4362f27 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 5af4362f27..f8d7883f55 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 b61afdfd085808f4c3a9b072edc98cdf2084f7a1 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 45bd21bcfa..3bb017a3aa 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 bfc9dda1f6bc9efa9e2616c98ba38c3b52f2ad3f 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 63521815df..7cd4f195ba 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 a029e689d81fd099d0a129bf0cdacda2b4b67762 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 7cd4f195ba..29b83bebab 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 f8d7883f55..52a8c2b77e 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 a06a8cf1d1..5b55b96b4b 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 52a8c2b77e..6e13a59b5c 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 2e9fc9f4ef..1b337338e9 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 2999415454..71239dba32 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 3bb017a3aa..01d38b1855 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 7e4e1745afb7ac09c65d3fe6cf7bffbc22eb8b84 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 18 Dec 2019 09:36:26 +0100 Subject: [PATCH 115/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 6e13a59b5c..d10447cc66 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 1404dba81ca9ae35bbe9beb147079795e7e8dd37 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 18 Dec 2019 09:56:38 +0100 Subject: [PATCH 116/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 523cd2bd31..79ebd28505 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 d10447cc66..7a2464351c 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 146b94264171180199309275c93e0a8553a135e0 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 18 Dec 2019 10:08:17 +0100 Subject: [PATCH 117/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 523cd2bd31..79ebd28505 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 d10447cc66..7a2464351c 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 1b337338e9..ea4584feee 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 1fa464af9653aa739e814fd8835c7ad52fdc4394 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 18 Dec 2019 10:34:26 +0100 Subject: [PATCH 118/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 4b127cd512..96a6292580 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 6c93107c42..8bcf948592 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 0499cea419..f789b73174 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 c9045929be..1a0c6f1b7f 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 1f53c9b692..f3045466e1 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 0000000000..4f66b3274a --- /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 89e8c0f629..b25d15af58 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 d50f6e395c..aee8b74018 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 91627631f4..433422d997 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 7f009b8147..68bb85a988 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 664b0e3a1d..98abdda280 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 ce3debfb52..7137527e9f 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 c2942a4ea3..9f173f6ea0 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 ae32bd2d37..1d4e69763e 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 9f3bc05391..5f5a861da3 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 8b5cbf483c..e9df4c5b5c 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 9af6048abf..8199bde031 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 03ef7e67d6..036344b224 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 b6ebf1ac09..7ab0c47b27 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 1d2996986f..a296553d62 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 0ec8b36ee3..d503f0c64a 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 e587509ac7..a8b88dd037 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 a28bb61f28..5b27c8870c 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 bd31527b1d..e07ccd7fdd 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 edb244b347..2eb316be0f 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 33e526083a..90ef017fcd 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 7cce60367d..5118af036d 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 b3d7c0e4fe..ad5be88d8c 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 cc03d4a24c..543c44e775 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 29b83bebab..79ebd28505 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 9b8eaa8ec0..dbfd446b11 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 6e13a59b5c..7a2464351c 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 1b337338e9..ea4584feee 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 c359f76624..6721e8a33e 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 26e334def4..ebed49efe6 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 0a62ff6f35..c96a304ab3 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") From 3d08e8ae321a5c75976b336055a9bc0208c47507 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 18 Dec 2019 15:40:48 +0100 Subject: [PATCH 119/123] is path on removable drive --- src/slic3r/GUI/RemovableDriveManager.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 7a2464351c..d9cecc3e8d 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -380,9 +380,11 @@ bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path) { if (m_current_drives.empty()) return false; + std::size_t found = path.find_last_of("/"); + std::string new_path = path.substr(0,found); for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) { - if(compare_filesystem_id(path, (*it).path)) + if(compare_filesystem_id(new_path, (*it).path)) return true; } return false; From 7b95ec486f7ab2c6bff18fada8f8e0f08bfa9d58 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 19 Dec 2019 11:47:02 +0100 Subject: [PATCH 120/123] ommit last filename when checking if path is on drive --- src/slic3r/GUI/RemovableDriveManager.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index d9cecc3e8d..7369847551 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -116,7 +116,9 @@ bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path) { if (m_current_drives.empty()) return false; - int letter = PathGetDriveNumberA(path.c_str()); + std::size_t found = path.find_last_of("\\"); + std::string new_path = path.substr(0, found); + int letter = PathGetDriveNumberA(new_path.c_str()); for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) { char drive = (*it).path[0]; @@ -127,7 +129,9 @@ bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path) } std::string RemovableDriveManager::get_drive_from_path(const std::string& path) { - int letter = PathGetDriveNumberA(path.c_str()); + std::size_t found = path.find_last_of("\\"); + std::string new_path = path.substr(0, found); + int letter = PathGetDriveNumberA(new_path.c_str()); for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) { char drive = (*it).path[0]; @@ -391,10 +395,12 @@ bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path) } std::string RemovableDriveManager::get_drive_from_path(const std::string& path) { + std::size_t found = path.find_last_of("/"); + std::string new_path = path.substr(0, found); //check if same filesystem for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it) { - if (compare_filesystem_id(path, (*it).path)) + if (compare_filesystem_id(new_path, (*it).path)) return (*it).path; } return ""; From d7698a36cbf0752a00fc5bd9789ffc2668e5e6d0 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 19 Dec 2019 14:19:41 +0100 Subject: [PATCH 121/123] changes in plater.cpp --- src/slic3r/GUI/Plater.cpp | 26 +++++++++++------------- src/slic3r/GUI/RemovableDriveManager.cpp | 19 +++++++++-------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 174d6b1897..26647a729b 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3611,17 +3611,14 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt) } else if (wxGetApp().get_mode() == comSimple) show_action_buttons(false); - if(RemovableDriveManager::get_instance().get_is_writing()) - { - RemovableDriveManager::get_instance().set_is_writing(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)); + if(!canceled && RemovableDriveManager::get_instance().get_is_writing()) + { + //if (!RemovableDriveManager::get_instance().is_last_drive_removed()) + //{ + RemovableDriveManager::get_instance().set_is_writing(false); show_action_buttons(false); - } + //} } } @@ -4755,19 +4752,20 @@ void Plater::export_gcode() if (! output_path.empty()) { std::string path = output_path.string(); - RemovableDriveManager::get_instance().set_is_writing(true); - RemovableDriveManager::get_instance().update(0, true); p->export_gcode(std::move(output_path), PrintHostJob()); + + RemovableDriveManager::get_instance().update(0, false); RemovableDriveManager::get_instance().set_last_save_path(path); - /* + RemovableDriveManager::get_instance().verify_last_save_path(); + if(!RemovableDriveManager::get_instance().is_last_drive_removed()) { + RemovableDriveManager::get_instance().set_is_writing(true); RemovableDriveManager::get_instance().erase_callbacks(); RemovableDriveManager::get_instance().add_callback(std::bind(&Plater::drive_ejected_callback, this)); } - */ + } - } void Plater::export_stl(bool extended, bool selection_only) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 7369847551..603994770b 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -449,7 +449,11 @@ bool RemovableDriveManager::update(const long time,const bool check) } } search_for_drives(); - if(check)check_and_notify(); + if (m_drives_count != m_current_drives.size()) + { + if (check)check_and_notify(); + m_drives_count = m_current_drives.size(); + } return !m_current_drives.empty(); } @@ -491,16 +495,12 @@ std::vector RemovableDriveManager::get_all_drives() } 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_verified && !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) { - for (auto it = m_callbacks.begin(); it != m_callbacks.end(); ++it) - { - (*it)(); - } + (*it)(); } - m_drives_count = m_current_drives.size(); } } void RemovableDriveManager::add_callback(std::function callback) @@ -524,6 +524,9 @@ void RemovableDriveManager::verify_last_save_path() m_last_save_path_verified = true; m_last_save_path = last_drive; m_last_save_name = get_drive_name(last_drive); + }else + { + reset_last_save_path(); } } std::string RemovableDriveManager::get_drive_name(const std::string& path) From 8d52663871173ac8c4ec80ef538861eed4dfc8b5 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 19 Dec 2019 16:27:48 +0100 Subject: [PATCH 122/123] free space check linux + mac --- src/slic3r/GUI/RemovableDriveManager.cpp | 28 +++++++++++++++--------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 7369847551..4279fe62cc 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -20,6 +20,7 @@ GUID WceusbshGUID = { 0x25dbce51, 0x6c8f, 0x4a72, #include #include #include +#include #endif namespace Slic3r { @@ -309,20 +310,27 @@ void RemovableDriveManager::inspect_file(const std::string &path, const std::str //if not same file system - could be removable drive if(!compare_filesystem_id(path, parent_path)) { - //user id - struct stat buf; - stat(path.c_str(), &buf); - uid_t uid = buf.st_uid; - std::string username(std::getenv("USER")); - struct passwd *pw = getpwuid(uid); - if(pw != 0) + //free space + std::filesystem::space_info fs_si = std::filesystem::space(path); + //std::cout << "Free space: " << fs_si.free << "Available space: " << fs_si.available << " " << path << '\n'; + if(fs_si.free != 0 && fs_si.available != 0) { - if(pw->pw_name == username) + //user id + struct stat buf; + stat(path.c_str(), &buf); + uid_t uid = buf.st_uid; + std::string username(std::getenv("USER")); + struct passwd *pw = getpwuid(uid); + if(pw != 0) { - std::string name = basename(const_cast(path.c_str())); - m_current_drives.push_back(DriveData(name,path)); + if(pw->pw_name == username) + { + std::string name = basename(const_cast(path.c_str())); + m_current_drives.push_back(DriveData(name,path)); + } } } + } } bool RemovableDriveManager::compare_filesystem_id(const std::string &path_a, const std::string &path_b) From 74e24213e6f960d61d2df1694b24adb5d4a33dab Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 19 Dec 2019 17:05:23 +0100 Subject: [PATCH 123/123] boost::filesystem instead std:: --- 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 23ab4bb7f6..353337e473 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -20,7 +20,7 @@ GUID WceusbshGUID = { 0x25dbce51, 0x6c8f, 0x4a72, #include #include #include -#include +#include #endif namespace Slic3r { @@ -311,9 +311,9 @@ void RemovableDriveManager::inspect_file(const std::string &path, const std::str if(!compare_filesystem_id(path, parent_path)) { //free space - std::filesystem::space_info fs_si = std::filesystem::space(path); + boost::filesystem::space_info si = boost::filesystem::space(path); //std::cout << "Free space: " << fs_si.free << "Available space: " << fs_si.available << " " << path << '\n'; - if(fs_si.free != 0 && fs_si.available != 0) + if(si.available != 0) { //user id struct stat buf;