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 60f4edf47..67d8bd8cf 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 000000000..44d4181d1 --- /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 000000000..cab58fee6 --- /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 6dcbc60b7..bb196d3fd 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 44d4181d1..ae718b7d3 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 cab58fee6..c503fdf18 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 67d8bd8cf..320f33751 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 ae718b7d3..53515ccdc 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 c503fdf18..8270c0f0f 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 320f33751..16f045966 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 789271581..bbfa9d932 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 53515ccdc..776334bf2 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 8270c0f0f..3de9d72ce 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 776334bf2..2d1f4ba6f 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 a74c6b0c0..35c11f021 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 2d1f4ba6f..235e1ccbe 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 3de9d72ce..c83b8033c 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 235e1ccbe..a1a5d7dd9 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 c83b8033c..9f3ebf326 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 35c11f021..10eb4ab59 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 bbfa9d932..74b2d1239 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 a1a5d7dd9..777085165 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 9f3ebf326..f3abc4207 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 777085165..4368d06b6 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 f3abc4207..43e47a086 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 10eb4ab59..c36c2748d 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 4368d06b6..ec730692f 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 43e47a086..b465b1c1b 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 ec730692f..9b3020e79 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 9b3020e79..bdc172740 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 bdc172740..99520b842 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 99520b842..e1ab1626c 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 e1ab1626c..3ff5735f9 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 3ff5735f9..7216763ee 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 7216763ee..c859a5d87 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 c859a5d87..3d77606c8 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 3d77606c8..0665e57dc 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 0665e57dc..a655425fc 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 c36c2748d..37753a0de 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 5d967cb6c..d1ce50f41 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 a655425fc..146bebc11 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 c65a7fe62..be5ae5968 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 37753a0de..ed5371e66 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 146bebc11..e94ea6918 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 be5ae5968..906667244 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 e94ea6918..6581d5361 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 906667244..741b4424a 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 6581d5361..1fbc33fc5 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 741b4424a..8d9e65c47 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 ed5371e66..90e6cd4bd 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 1fbc33fc5..5daa9eb26 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 8d9e65c47..210d89477 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 03413f933..6a14a1b3f 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 5daa9eb26..166728e68 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 210d89477..501c16b71 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 000000000..a1358625f --- /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 90e6cd4bd..1b2fe919a 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 6a14a1b3f..9d51f6219 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 501c16b71..04bbe48b5 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 000000000..8f783c2d2 --- /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 a1358625f..e4e324654 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 166728e68..8145c9076 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 04bbe48b5..c4f55029b 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 e4e324654..99abd7386 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 8145c9076..50e2b6359 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 c4f55029b..7109bbd07 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 8f783c2d2..4a5fa2515 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 99abd7386..7e8b56c59 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 50e2b6359..763113ea2 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 7109bbd07..202680328 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 4a5fa2515..299941545 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 7e8b56c59..25fa6da09 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 763113ea2..c5dca1bd5 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 d1ce50f41..b50f6f150 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 5c36dbf5e..af4b989c4 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 202680328..cbf6f53aa 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 25fa6da09..269a2255b 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 000000000..fe8de635d --- /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 c5dca1bd5..164b6e38a 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 cbf6f53aa..a5027a5ad 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 269a2255b..d32b7b278 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 b50f6f150..e94e0a4e6 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 af4b989c4..a247f8292 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 164b6e38a..1a964f889 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 a5027a5ad..f41294001 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 1b2fe919a..fc25b4f29 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 e94e0a4e6..905d56e90 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 1a964f889..49bf59e11 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 f41294001..49df41482 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 d32b7b278..7a1108541 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 905d56e90..0300670e4 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 fc25b4f29..8e450f497 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 49bf59e11..284c224fb 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 49df41482..9eea355f7 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 7a1108541..45bd21bcf 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 fc25b4f29..8e450f497 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 49bf59e11..dc8469d9a 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 afe5ee739..ab2dd10eb 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 0300670e4..a0e453abc 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 8e450f497..258e33871 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 ab2dd10eb..d5f224409 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 258e33871..bdaf8f8a7 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 a0e453abc..74a26c400 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 d5f224409..7ab34204b 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 74a26c400..3ecb174ce 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 7ab34204b..cd360b580 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 9eea355f7..b4fc71e26 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 3ecb174ce..417afa0a9 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 cd360b580..02681b7da 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 b4fc71e26..ac1645df7 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 417afa0a9..0dc09d9d8 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 417afa0a9..814bcde0c 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 849313897..735e704ee 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 7841b62fe..951f7ea8f 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 d33d945ef..4f3272e26 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 000000000..44d4181d1 --- /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 000000000..cab58fee6 --- /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 bcddcfe06..2d7b99b73 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 44d4181d1..ae718b7d3 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 cab58fee6..c503fdf18 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 4f3272e26..26ca07082 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 ae718b7d3..53515ccdc 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 c503fdf18..8270c0f0f 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 26ca07082..705582251 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 c8267331d..efe0ab7b3 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 53515ccdc..776334bf2 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 8270c0f0f..3de9d72ce 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 776334bf2..2d1f4ba6f 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 e02dd5f6e..3d09e3573 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 2d1f4ba6f..235e1ccbe 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 3de9d72ce..c83b8033c 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 235e1ccbe..a1a5d7dd9 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 c83b8033c..9f3ebf326 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 3d09e3573..e33fc0d2e 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 efe0ab7b3..3e3827926 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 a1a5d7dd9..777085165 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 9f3ebf326..f3abc4207 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 777085165..4368d06b6 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 f3abc4207..43e47a086 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 e33fc0d2e..e6c92cd0a 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 4368d06b6..ec730692f 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 43e47a086..b465b1c1b 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 ec730692f..9b3020e79 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 9b3020e79..bdc172740 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 bdc172740..99520b842 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 99520b842..e1ab1626c 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 e1ab1626c..3ff5735f9 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 3ff5735f9..7216763ee 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 7216763ee..c859a5d87 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 c859a5d87..3d77606c8 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 3d77606c8..0665e57dc 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 0665e57dc..a655425fc 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 e6c92cd0a..0d608876e 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 3e3827926..b8b2f45e8 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 a655425fc..146bebc11 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 c65a7fe62..be5ae5968 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 0d608876e..28812dcf4 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 146bebc11..e94ea6918 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 be5ae5968..906667244 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 e94ea6918..6581d5361 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 906667244..741b4424a 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 6581d5361..1fbc33fc5 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 741b4424a..8d9e65c47 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 28812dcf4..72c84ba79 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 1fbc33fc5..5daa9eb26 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 8d9e65c47..210d89477 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 2d7b99b73..246f1365b 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 5daa9eb26..166728e68 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 210d89477..501c16b71 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 000000000..a1358625f --- /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 72c84ba79..e13701f61 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 246f1365b..a06a8cf1d 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 501c16b71..04bbe48b5 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 000000000..8f783c2d2 --- /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 a1358625f..e4e324654 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 166728e68..8145c9076 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 04bbe48b5..c4f55029b 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 e4e324654..99abd7386 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 8145c9076..50e2b6359 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 c4f55029b..7109bbd07 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 8f783c2d2..4a5fa2515 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 99abd7386..7e8b56c59 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 50e2b6359..763113ea2 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 7109bbd07..202680328 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 4a5fa2515..299941545 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 7e8b56c59..25fa6da09 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 b8b2f45e8..7b5cef4ca 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 33140c4f5..528d65297 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 763113ea2..c5dca1bd5 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 202680328..cbf6f53aa 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 25fa6da09..269a2255b 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 c5dca1bd5..164b6e38a 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 cbf6f53aa..a5027a5ad 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 269a2255b..d32b7b278 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 000000000..fe8de635d --- /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 7b5cef4ca..ed60066e5 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 528d65297..d9a9af376 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 164b6e38a..1a964f889 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 a5027a5ad..f41294001 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 e13701f61..786a5901e 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 ed60066e5..7edf657be 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 1a964f889..49bf59e11 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 f41294001..49df41482 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 d32b7b278..7a1108541 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 7edf657be..8a96ac4d4 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 786a5901e..b83ecbedc 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 49bf59e11..dc8469d9a 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 dc8469d9a..afe5ee739 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 49df41482..9eea355f7 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 7a1108541..45bd21bcf 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 8a96ac4d4..d57864911 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 afe5ee739..ab2dd10eb 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 b83ecbedc..c9ed88f84 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 ab2dd10eb..d5f224409 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 c9ed88f84..f601cd4bc 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 d57864911..eb5f6d485 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 d5f224409..7ab34204b 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 eb5f6d485..cefe31e90 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 7ab34204b..cd360b580 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 9eea355f7..b4fc71e26 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 cefe31e90..910de4722 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 cd360b580..02681b7da 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 b4fc71e26..ac1645df7 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 910de4722..52255d176 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 705582251..f24bde242 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 02681b7da..ba5ab5072 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 ac1645df7..a5abde72d 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 ba5ab5072..e61332045 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 a5abde72d..157f670b3 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 f24bde242..9f294a3b6 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 e61332045..30f6c9b29 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 157f670b3..c00164446 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 9f294a3b6..e27fa1be6 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 52255d176..aff162401 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 30f6c9b29..02681b7da 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 c00164446..1e5d240f0 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 e27fa1be6..d33d945ef 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 aff162401..52255d176 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 02681b7da..77a387aaf 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 1e5d240f0..fa42f5e73 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 52255d176..02f8ace07 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 02f8ace07..cff3164e8 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 302a5e521..e64a3fce5 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 7841b62fe..951f7ea8f 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 72d01b41d..fa18bd5ea 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 e64a3fce5..c359f7662 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 951f7ea8f..26e334def 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 72d01b41d..f1bdbb23e 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 1c2a29b0b..535d62f83 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 ce29120ab..63521815d 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 535d62f83..5af4362f2 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 5af4362f2..f8d7883f5 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 45bd21bcf..3bb017a3a 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 63521815d..7cd4f195b 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 7cd4f195b..29b83beba 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 f8d7883f5..52a8c2b77 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 a06a8cf1d..5b55b96b4 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 52a8c2b77..6e13a59b5 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 2e9fc9f4e..1b337338e 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 299941545..71239dba3 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 3bb017a3a..01d38b185 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 9bf09e2874bdf4026867a9daa6a56378a546dccb Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 17 Dec 2019 16:50:00 +0100 Subject: [PATCH 115/123] Fix linking of OpenVDB in debug mode on multi conf generators. --- cmake/modules/FindOpenVDB.cmake | 50 +++++++++++++++++++++++++++------ deps/CMakeLists.txt | 1 + 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/cmake/modules/FindOpenVDB.cmake b/cmake/modules/FindOpenVDB.cmake index 9afe8a235..8c91fac05 100644 --- a/cmake/modules/FindOpenVDB.cmake +++ b/cmake/modules/FindOpenVDB.cmake @@ -203,20 +203,44 @@ if(UNIX AND OPENVDB_USE_STATIC_LIBS) endif() set(OpenVDB_LIB_COMPONENTS "") +set(OpenVDB_DEBUG_SUFFIX "d" CACHE STRING "Suffix for the debug libraries") + +get_property(_is_multi GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) set(LIB_NAME ${COMPONENT}) - find_library(OpenVDB_${COMPONENT}_LIBRARY ${LIB_NAME} lib${LIB_NAME} + + find_library(OpenVDB_${COMPONENT}_LIBRARY_RELEASE ${LIB_NAME} lib${LIB_NAME} PATHS ${_OPENVDB_LIBRARYDIR_SEARCH_DIRS} PATH_SUFFIXES ${OPENVDB_PATH_SUFFIXES} ) - list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY}) - if(OpenVDB_${COMPONENT}_LIBRARY) - set(OpenVDB_${COMPONENT}_FOUND TRUE) - else() - set(OpenVDB_${COMPONENT}_FOUND FALSE) - endif() + find_library(OpenVDB_${COMPONENT}_LIBRARY_DEBUG ${LIB_NAME}${OpenVDB_DEBUG_SUFFIX} lib${LIB_NAME}${OpenVDB_DEBUG_SUFFIX} + PATHS ${_OPENVDB_LIBRARYDIR_SEARCH_DIRS} + PATH_SUFFIXES ${OPENVDB_PATH_SUFFIXES} + ) + + if (_is_multi) + list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY_RELEASE} ${OpenVDB_${COMPONENT}_LIBRARY_DEBUG}) + + if(OpenVDB_${COMPONENT}_LIBRARY_RELEASE AND ${OpenVDB_${COMPONENT}_LIBRARY_DEBUG}) + set(OpenVDB_${COMPONENT}_FOUND TRUE) + else() + set(OpenVDB_${COMPONENT}_FOUND FALSE) + endif() + else () + string(TOUPPER "${CMAKE_BUILD_TYPE}" _BUILD_TYPE) + + set(OpenVDB_${COMPONENT}_LIBRARY ${OpenVDB_${COMPONENT}_LIBRARY_${_BUILD_TYPE}}) + + list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY}) + + if(OpenVDB_${COMPONENT}_LIBRARY) + set(OpenVDB_${COMPONENT}_FOUND TRUE) + else() + set(OpenVDB_${COMPONENT}_FOUND FALSE) + endif() + endif () endforeach() if(UNIX AND OPENVDB_USE_STATIC_LIBS) @@ -465,7 +489,6 @@ foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) if(NOT TARGET OpenVDB::${COMPONENT}) add_library(OpenVDB::${COMPONENT} UNKNOWN IMPORTED) set_target_properties(OpenVDB::${COMPONENT} PROPERTIES - IMPORTED_LOCATION "${OpenVDB_${COMPONENT}_LIBRARY}" INTERFACE_COMPILE_OPTIONS "${OpenVDB_DEFINITIONS}" INTERFACE_INCLUDE_DIRECTORIES "${OpenVDB_INCLUDE_DIR}" IMPORTED_LINK_DEPENDENT_LIBRARIES "${_OPENVDB_HIDDEN_DEPENDENCIES}" # non visible deps @@ -473,6 +496,17 @@ foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) INTERFACE_COMPILE_FEATURES cxx_std_11 ) + if (_is_multi) + set_target_properties(OpenVDB::${COMPONENT} PROPERTIES + IMPORTED_LOCATION_RELEASE "${OpenVDB_${COMPONENT}_LIBRARY_RELEASE}" + IMPORTED_LOCATION_DEBUG "${OpenVDB_${COMPONENT}_LIBRARY_DEBUG}" + ) + else () + set_target_properties(OpenVDB::${COMPONENT} PROPERTIES + IMPORTED_LOCATION "${OpenVDB_${COMPONENT}_LIBRARY}" + ) + endif () + if (OPENVDB_USE_STATIC_LIBS) set_target_properties(OpenVDB::${COMPONENT} PROPERTIES INTERFACE_COMPILE_DEFINITIONS "OPENVDB_STATICLIB;OPENVDB_OPENEXR_STATICLIB" diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index aeb078172..3935e38c3 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -47,6 +47,7 @@ message(STATUS "PrusaSlicer deps debug build: ${DEP_DEBUG}") find_package(Git REQUIRED) +get_property(_is_multi GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) function(prusaslicer_add_cmake_project projectname) cmake_parse_arguments(P_ARGS "" "INSTALL_DIR;BUILD_COMMAND;INSTALL_COMMAND" "CMAKE_ARGS" ${ARGN}) From ab1bcad8c7f7217df49e93c4bf459594e69fb8a8 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 17 Dec 2019 16:56:11 +0100 Subject: [PATCH 116/123] Only consider openvdb debug if necessary. --- cmake/modules/FindOpenVDB.cmake | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmake/modules/FindOpenVDB.cmake b/cmake/modules/FindOpenVDB.cmake index 8c91fac05..8d8c1089b 100644 --- a/cmake/modules/FindOpenVDB.cmake +++ b/cmake/modules/FindOpenVDB.cmake @@ -223,7 +223,9 @@ foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) if (_is_multi) list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY_RELEASE} ${OpenVDB_${COMPONENT}_LIBRARY_DEBUG}) - if(OpenVDB_${COMPONENT}_LIBRARY_RELEASE AND ${OpenVDB_${COMPONENT}_LIBRARY_DEBUG}) + list(FIND CMAKE_CONFIGURATION_TYPES "Debug" _has_debug) + + if(OpenVDB_${COMPONENT}_LIBRARY_RELEASE AND (_has_debug LESS 0 OR OpenVDB_${COMPONENT}_LIBRARY_DEBUG)) set(OpenVDB_${COMPONENT}_FOUND TRUE) else() set(OpenVDB_${COMPONENT}_FOUND FALSE) From 2222b0cdc9ea4d1ae247aa0ed7fd8043c352166c Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 17 Dec 2019 17:08:43 +0100 Subject: [PATCH 117/123] Grab the release in debug mode if there is no debug when not on msvc --- cmake/modules/FindOpenVDB.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmake/modules/FindOpenVDB.cmake b/cmake/modules/FindOpenVDB.cmake index 8d8c1089b..b75bc6ed0 100644 --- a/cmake/modules/FindOpenVDB.cmake +++ b/cmake/modules/FindOpenVDB.cmake @@ -235,6 +235,10 @@ foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) set(OpenVDB_${COMPONENT}_LIBRARY ${OpenVDB_${COMPONENT}_LIBRARY_${_BUILD_TYPE}}) + if (NOT MSVC AND NOT OpenVDB_${COMPONENT}_LIBRARY) + set(OpenVDB_${COMPONENT}_LIBRARY ${OpenVDB_${COMPONENT}_LIBRARY_RELEASE}) + endif () + list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY}) if(OpenVDB_${COMPONENT}_LIBRARY) From 7650732c61162d42e457d9db887961908cbd298d Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 18 Dec 2019 09:06:21 +0100 Subject: [PATCH 118/123] Show context menu for a multi-object selection on 3DScene, add "Reload from disk" item for this menu --- src/slic3r/GUI/GUI_ObjectList.cpp | 11 ++++++++--- src/slic3r/GUI/GUI_ObjectList.hpp | 4 ++-- src/slic3r/GUI/Plater.cpp | 3 +++ 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index c0520cb9a..a058de805 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -3874,8 +3874,8 @@ void ObjectList::show_multi_selection_menu() GetSelections(sels); for (const wxDataViewItem& item : sels) - if (!(m_objects_model->GetItemType(item) & (itVolume | itObject))) - // show this menu only for Object(s)/Volume(s) selection + if (!(m_objects_model->GetItemType(item) & (itVolume | itObject | itInstance))) + // show this menu only for Objects(Instances mixed with Objects)/Volumes selection return; wxMenu* menu = new wxMenu(); @@ -3885,7 +3885,12 @@ void ObjectList::show_multi_selection_menu() _(L("Select extruder number for selected objects and/or parts")), [this](wxCommandEvent&) { extruder_selection(); }, "", menu); - PopupMenu(menu); + append_menu_item(menu, wxID_ANY, _(L("Reload from disk")), _(L("Reload the selected volumes from disk")), + [this](wxCommandEvent&) { wxGetApp().plater()->reload_from_disk(); }, "", menu, []() { + return wxGetApp().plater()->can_reload_from_disk(); + }, wxGetApp().plater()); + + wxGetApp().plater()->PopupMenu(menu); } void ObjectList::extruder_selection() diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 73b23453b..a5a72ad8c 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -366,6 +366,8 @@ public: void update_printable_state(int obj_idx, int instance_idx); void toggle_printable_state(wxDataViewItem item); + void show_multi_selection_menu(); + private: #ifdef __WXOSX__ // void OnChar(wxKeyEvent& event); @@ -384,8 +386,6 @@ private: void OnEditingStarted(wxDataViewEvent &event); #endif /* __WXMSW__ */ void OnEditingDone(wxDataViewEvent &event); - - void show_multi_selection_menu(); void extruder_selection(); void set_extruder_for_selected_items(const int extruder) const ; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index ef891b3b3..107d55de0 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3615,7 +3615,10 @@ void Plater::priv::on_right_click(RBtnEvent& evt) if (evt.data.second) // right button was clicked on empty space menu = &default_menu; else + { + sidebar->obj_list()->show_multi_selection_menu(); return; + } } else { From 7e4e1745afb7ac09c65d3fe6cf7bffbc22eb8b84 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 18 Dec 2019 09:36:26 +0100 Subject: [PATCH 119/123] bug fix - using two devices --- src/slic3r/GUI/RemovableDriveManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 6e13a59b5..d10447cc6 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 120/123] set_did_eject method --- src/slic3r/GUI/Plater.cpp | 1 + src/slic3r/GUI/RemovableDriveManager.cpp | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 523cd2bd3..79ebd2850 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 d10447cc6..7a2464351 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 121/123] set_did_eject method --- src/slic3r/GUI/Plater.cpp | 1 + src/slic3r/GUI/RemovableDriveManager.cpp | 4 ++++ src/slic3r/GUI/RemovableDriveManager.hpp | 1 + 3 files changed, 6 insertions(+) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 523cd2bd3..79ebd2850 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 d10447cc6..7a2464351 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 1b337338e..ea4584fee 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 8795f7dba86d0a7c08946be0d61513673c3d297e Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 18 Dec 2019 10:17:47 +0100 Subject: [PATCH 122/123] Trying to fix a compilation issue on Linux / OSX --- src/slic3r/GUI/wxExtensions.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 9b7de93cd..0c43be3a0 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -962,7 +962,7 @@ private: bool operator<(const TICK_CODE& other) const { return other.tick > this->tick; } bool operator>(const TICK_CODE& other) const { return other.tick < this->tick; } - int tick; + int tick = 0; std::string gcode = Slic3r::ColorChangeCode; int extruder = 0; std::string color; From 1fa464af9653aa739e814fd8835c7ad52fdc4394 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 18 Dec 2019 10:34:26 +0100 Subject: [PATCH 123/123] removableDriveManager bug fixes --- deps/CGAL/CGAL.cmake | 6 + deps/GMP/GMP.cmake | 2 +- resources/icons/thumb_down.svg | 2 +- resources/icons/thumb_up.svg | 2 +- src/hidapi/CMakeLists.txt | 2 +- src/hidapi/README.md | 5 + src/libslic3r/Format/3mf.cpp | 45 ++-- src/libslic3r/Format/AMF.cpp | 14 +- src/libslic3r/GCode.cpp | 40 ++-- src/libslic3r/GCode.hpp | 2 +- src/libslic3r/GCodeWriter.hpp | 5 + src/libslic3r/Model.cpp | 53 ++++- src/libslic3r/Model.hpp | 31 +-- src/libslic3r/Print.cpp | 4 +- src/libslic3r/PrintConfig.hpp | 6 - src/libslic3r/ShortestPath.cpp | 11 +- src/libslic3r/Slicing.cpp | 98 +++----- src/libslic3r/Slicing.hpp | 14 +- src/libslic3r/SlicingAdaptive.cpp | 246 ++++++++++++-------- src/libslic3r/SlicingAdaptive.hpp | 48 ++-- src/libslic3r/Technologies.hpp | 3 + src/slic3r/GUI/BackgroundSlicingProcess.cpp | 7 +- src/slic3r/GUI/GLCanvas3D.cpp | 72 +++--- src/slic3r/GUI/GLCanvas3D.hpp | 8 +- src/slic3r/GUI/GUI_Preview.cpp | 10 +- src/slic3r/GUI/ImGuiWrapper.cpp | 10 + src/slic3r/GUI/ImGuiWrapper.hpp | 2 + src/slic3r/GUI/Mouse3DController.cpp | 219 +++++++++++------ src/slic3r/GUI/Mouse3DController.hpp | 19 +- src/slic3r/GUI/Plater.cpp | 28 ++- src/slic3r/GUI/PresetBundle.cpp | 4 + src/slic3r/GUI/RemovableDriveManager.cpp | 5 + src/slic3r/GUI/RemovableDriveManager.hpp | 1 + src/slic3r/GUI/wxExtensions.cpp | 42 ++-- src/slic3r/GUI/wxExtensions.hpp | 17 +- version.inc | 6 +- 36 files changed, 620 insertions(+), 469 deletions(-) create mode 100644 src/hidapi/README.md diff --git a/deps/CGAL/CGAL.cmake b/deps/CGAL/CGAL.cmake index 4b127cd51..96a629258 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 6c93107c4..8bcf94859 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 0499cea41..f789b7317 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 c9045929b..1a0c6f1b7 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 1f53c9b69..f3045466e 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 000000000..4f66b3274 --- /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 89e8c0f62..b25d15af5 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 d50f6e395..aee8b7401 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 91627631f..433422d99 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 7f009b814..68bb85a98 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 664b0e3a1..98abdda28 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 ce3debfb5..7137527e9 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 c2942a4ea..9f173f6ea 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 ae32bd2d3..1d4e69763 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 9f3bc0539..5f5a861da 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 8b5cbf483..e9df4c5b5 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 9af6048ab..8199bde03 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 03ef7e67d..036344b22 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 b6ebf1ac0..7ab0c47b2 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 1d2996986..a296553d6 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 0ec8b36ee..d503f0c64 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 e587509ac..a8b88dd03 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 a28bb61f2..5b27c8870 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 bd31527b1..e07ccd7fd 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 edb244b34..2eb316be0 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 33e526083..90ef017fc 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 7cce60367..5118af036 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 b3d7c0e4f..ad5be88d8 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 cc03d4a24..543c44e77 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 29b83beba..79ebd2850 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 9b8eaa8ec..dbfd446b1 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 6e13a59b5..7a2464351 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 1b337338e..ea4584fee 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 c359f7662..6721e8a33 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 26e334def..ebed49efe 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 0a62ff6f3..c96a304ab 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")