PrusaSlicer-NonPlainar/src/slic3r/GUI/RemovableDriveManager.cpp

608 lines
16 KiB
C++
Raw Normal View History

2019-11-26 13:19:29 +00:00
#include "RemovableDriveManager.hpp"
#include <iostream>
2019-11-27 10:33:36 +00:00
#include "boost/nowide/convert.hpp"
2019-11-26 13:19:29 +00:00
2019-11-26 14:52:18 +00:00
#if _WIN32
#include <windows.h>
#include <tchar.h>
2019-11-27 10:33:36 +00:00
#include <winioctl.h>
2019-11-27 12:30:45 +00:00
#include <shlwapi.h>
2019-12-05 13:07:02 +00:00
#include <Dbt.h>
GUID WceusbshGUID = { 0x25dbce51, 0x6c8f, 0x4a72,
0x8a,0x6d,0xb5,0x4c,0x2b,0x4f,0xc8,0x35 };
2019-12-05 13:07:02 +00:00
2019-11-26 14:52:18 +00:00
#else
//linux includes
#include <errno.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <glob.h>
2019-11-28 15:35:22 +00:00
#include <pwd.h>
2019-12-19 16:05:23 +00:00
#include <boost/filesystem.hpp>
#include <boost/filesystem/convenience.hpp>
2019-11-26 14:52:18 +00:00
#endif
2019-11-26 13:19:29 +00:00
namespace Slic3r {
2019-12-03 09:09:53 +00:00
namespace GUI {
2019-11-26 14:52:18 +00:00
#if _WIN32
INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
2019-11-27 10:33:36 +00:00
void RemovableDriveManager::search_for_drives()
2019-11-26 13:19:29 +00:00
{
2019-11-27 10:33:36 +00:00
m_current_drives.clear();
2019-12-13 10:52:08 +00:00
//get logical drives flags by letter in alphabetical order
2019-11-27 13:30:10 +00:00
DWORD drives_mask = GetLogicalDrives();
2019-11-26 13:19:29 +00:00
for (size_t i = 0; i < 26; i++)
{
2019-11-27 13:30:10 +00:00
if(drives_mask & (1 << i))
2019-11-26 13:19:29 +00:00
{
std::string path (1,(char)('A' + i));
path+=":";
2019-11-27 13:30:10 +00:00
UINT drive_type = GetDriveTypeA(path.c_str());
2019-12-13 10:52:08 +00:00
// DRIVE_REMOVABLE on W are sd cards and usb thumbnails (not usb harddrives)
2019-11-27 13:30:10 +00:00
if (drive_type == DRIVE_REMOVABLE)
2019-11-26 13:19:29 +00:00
{
// get name of drive
2019-12-13 17:02:25 +00:00
std::wstring wpath = boost::nowide::widen(path);//std::wstring(path.begin(), path.end());
2019-11-27 13:30:10 +00:00
std::wstring volume_name;
volume_name.resize(1024);
std::wstring file_system_name;
file_system_name.resize(1024);
LPWSTR lp_volume_name_buffer = new wchar_t;
BOOL error = GetVolumeInformationW(wpath.c_str(), &volume_name[0], sizeof(volume_name), NULL, NULL, NULL, &file_system_name[0], sizeof(file_system_name));
2019-11-26 13:19:29 +00:00
if(error != 0)
{
2019-12-13 17:02:25 +00:00
volume_name.erase(std::find(volume_name.begin(), volume_name.end(), '\0'), volume_name.end());
2019-12-13 10:52:08 +00:00
/*
2019-11-27 13:30:10 +00:00
if (volume_name == L"")
2019-11-26 13:19:29 +00:00
{
2019-11-27 13:30:10 +00:00
volume_name = L"REMOVABLE DRIVE";
2019-11-26 13:19:29 +00:00
}
2019-12-13 10:52:08 +00:00
*/
2019-11-27 13:30:10 +00:00
if (file_system_name != L"")
2019-11-26 13:19:29 +00:00
{
2019-11-27 13:30:10 +00:00
ULARGE_INTEGER free_space;
GetDiskFreeSpaceExA(path.c_str(), &free_space, NULL, NULL);
if (free_space.QuadPart > 0)
2019-11-26 13:19:29 +00:00
{
2019-12-03 09:55:38 +00:00
path += "\\";
2019-11-27 13:30:10 +00:00
m_current_drives.push_back(DriveData(boost::nowide::narrow(volume_name), path));
2019-11-26 13:19:29 +00:00
}
}
}
}
}
}
}
2019-11-27 10:33:36 +00:00
void RemovableDriveManager::eject_drive(const std::string &path)
2019-11-26 13:19:29 +00:00
{
2019-11-27 10:33:36 +00:00
if(m_current_drives.empty())
2019-11-26 13:19:29 +00:00
return;
2019-11-27 10:33:36 +00:00
for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
2019-11-26 13:19:29 +00:00
{
if ((*it).path == path)
{
2019-12-13 10:52:08 +00:00
// get handle to device
2019-11-27 10:33:36 +00:00
std::string mpath = "\\\\.\\" + path;
2019-12-03 09:55:38 +00:00
mpath = mpath.substr(0, mpath.size() - 1);
2019-11-27 10:33:36 +00:00
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);
2019-12-13 10:52:08 +00:00
//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
2019-12-11 16:02:12 +00:00
DeviceIoControl(handle, FSCTL_LOCK_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr);
DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr);
2019-12-13 10:52:08 +00:00
// some implemenatations also calls IOCTL_STORAGE_MEDIA_REMOVAL here but it returns error to me
2019-11-27 10:33:36 +00:00
BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr);
2019-11-27 13:30:10 +00:00
if (error == 0)
{
2019-12-11 16:02:12 +00:00
CloseHandle(handle);
2019-11-27 10:33:36 +00:00
std::cerr << "Ejecting " << mpath << " failed " << deviceControlRetVal << " " << GetLastError() << " \n";
2019-12-03 09:09:53 +00:00
return;
2019-11-27 13:30:10 +00:00
}
2019-12-11 16:02:12 +00:00
CloseHandle(handle);
m_did_eject = true;
2019-11-27 10:33:36 +00:00
m_current_drives.erase(it);
2019-11-26 13:19:29 +00:00
break;
}
}
}
2019-11-27 13:30:10 +00:00
bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path)
{
if (m_current_drives.empty())
return false;
std::size_t found = path.find_last_of("\\");
std::string new_path = path.substr(0, found);
int letter = PathGetDriveNumberA(new_path.c_str());
2019-11-27 13:30:10 +00:00
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;
}
2019-12-05 13:07:02 +00:00
std::string RemovableDriveManager::get_drive_from_path(const std::string& path)
{
std::size_t found = path.find_last_of("\\");
std::string new_path = path.substr(0, found);
int letter = PathGetDriveNumberA(new_path.c_str());
2019-12-05 13:07:02 +00:00
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 "";
}
2019-11-28 12:38:08 +00:00
void RemovableDriveManager::register_window()
{
2019-12-12 13:56:30 +00:00
//creates new unvisible window that is recieving callbacks from system
2019-12-13 10:52:08 +00:00
// structure to register
2019-11-28 12:38:08 +00:00
WNDCLASSEX wndClass;
wndClass.cbSize = sizeof(WNDCLASSEX);
wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
wndClass.hInstance = reinterpret_cast<HINSTANCE>(GetModuleHandle(0));
2019-12-13 10:52:08 +00:00
wndClass.lpfnWndProc = reinterpret_cast<WNDPROC>(WinProcCallback);//this is callback
2019-11-28 12:38:08 +00:00
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);
2019-12-05 13:07:02 +00:00
wndClass.lpszClassName = L"PrusaSlicer_aux_class";
2019-11-28 12:38:08 +00:00
wndClass.lpszMenuName = NULL;
wndClass.hIconSm = wndClass.hIcon;
if(!RegisterClassEx(&wndClass))
{
DWORD err = GetLastError();
return;
}
2019-12-05 13:07:02 +00:00
HWND hWnd = CreateWindowEx(
WS_EX_NOACTIVATE,
2019-12-05 13:07:02 +00:00
L"PrusaSlicer_aux_class",
L"PrusaSlicer_aux_wnd",
WS_DISABLED, // style
2019-12-05 13:07:02 +00:00
CW_USEDEFAULT, 0,
640, 480,
NULL, NULL,
GetModuleHandle(NULL),
2019-12-05 13:07:02 +00:00
NULL);
if(hWnd == NULL)
{
DWORD err = GetLastError();
}
//ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
2019-12-05 13:07:02 +00:00
}
2019-12-05 13:07:02 +00:00
INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
2019-12-13 10:52:08 +00:00
// 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
2019-12-05 13:07:02 +00:00
LRESULT lRet = 1;
static HDEVNOTIFY hDeviceNotify;
2019-12-05 13:07:02 +00:00
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;
2019-12-12 13:56:30 +00:00
hDeviceNotify = RegisterDeviceNotification(hWnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
2019-12-05 13:07:02 +00:00
break;
2019-12-11 16:02:12 +00:00
2019-12-05 13:07:02 +00:00
case WM_DEVICECHANGE:
{
2019-12-13 10:52:08 +00:00
// here is the important
if(wParam == DBT_DEVICEREMOVECOMPLETE)
2019-12-05 13:07:02 +00:00
{
2019-12-11 13:53:28 +00:00
- RemovableDriveManager::get_instance().update(0, true);
2019-12-05 13:07:02 +00:00
}
}
break;
2019-12-11 16:02:12 +00:00
2019-12-05 13:07:02 +00:00
default:
// Send all other messages on to the default windows handler.
lRet = DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return lRet;
2019-11-28 12:38:08 +00:00
}
2019-11-26 14:52:18 +00:00
#else
2019-11-27 10:33:36 +00:00
void RemovableDriveManager::search_for_drives()
2019-11-26 14:52:18 +00:00
{
2019-12-11 16:39:34 +00:00
m_current_drives.clear();
#if __APPLE__
2019-12-13 10:52:08 +00:00
// if on macos obj-c class will enumerate
2019-12-10 13:10:47 +00:00
if(m_rdmmm)
{
m_rdmmm->list_devices();
}
#else
2019-12-11 16:39:34 +00:00
2019-11-26 14:52:18 +00:00
//search /media/* folder
2019-11-28 15:35:22 +00:00
search_path("/media/*", "/media");
2019-11-26 14:52:18 +00:00
2019-12-04 09:05:18 +00:00
//search /Volumes/* folder (OSX)
2020-01-06 10:59:24 +00:00
//search_path("/Volumes/*", "/Volumes");
2019-11-28 15:35:22 +00:00
std::string path(std::getenv("USER"));
std::string pp(path);
//std::cout << "user: "<< path << "\n";
2019-12-04 10:47:47 +00:00
//if program is run with sudo, we have to search for all users
// but do we want that?
/*
if(path == "root"){
2019-11-28 15:35:22 +00:00
while (true) {
passwd* entry = getpwent();
if (!entry) {
break;
}
path = entry->pw_name;
pp = path;
//search /media/USERNAME/* folder
pp = "/media/"+pp;
path = "/media/" + path + "/*";
search_path(path, pp);
2019-11-26 14:52:18 +00:00
2019-11-28 15:35:22 +00:00
//search /run/media/USERNAME/* folder
path = "/run" + path;
pp = "/run"+pp;
search_path(path, pp);
}
endpwent();
}else
2019-12-04 10:47:47 +00:00
*/
2019-11-28 15:35:22 +00:00
{
//search /media/USERNAME/* folder
pp = "/media/"+pp;
path = "/media/" + path + "/*";
search_path(path, pp);
2019-11-26 14:52:18 +00:00
2019-11-28 15:35:22 +00:00
//search /run/media/USERNAME/* folder
path = "/run" + path;
pp = "/run"+pp;
search_path(path, pp);
2019-11-26 14:52:18 +00:00
2019-11-28 15:35:22 +00:00
}
2019-12-10 13:10:47 +00:00
#endif
2019-11-26 14:52:18 +00:00
}
2019-11-28 15:35:22 +00:00
void RemovableDriveManager::search_path(const std::string &path,const std::string &parent_path)
2019-11-26 14:52:18 +00:00
{
glob_t globbuf;
globbuf.gl_offs = 2;
int error = glob(path.c_str(), GLOB_TILDE, NULL, &globbuf);
2019-11-28 15:35:22 +00:00
if(error == 0)
2019-11-26 14:52:18 +00:00
{
2019-11-27 13:30:10 +00:00
for(size_t i = 0; i < globbuf.gl_pathc; i++)
2019-11-26 14:52:18 +00:00
{
2019-12-10 13:41:49 +00:00
inspect_file(globbuf.gl_pathv[i], parent_path);
2019-11-26 14:52:18 +00:00
}
2019-11-28 15:35:22 +00:00
}else
{
//if error - path probably doesnt exists so function just exits
//std::cout<<"glob error "<< error<< "\n";
2019-11-26 14:52:18 +00:00
}
2019-11-27 13:30:10 +00:00
2019-11-26 14:52:18 +00:00
globfree(&globbuf);
}
2019-12-10 13:10:47 +00:00
void RemovableDriveManager::inspect_file(const std::string &path, const std::string &parent_path)
{
2019-12-13 10:52:08 +00:00
//confirms if the file is removable drive and adds it to vector
2019-12-10 13:10:47 +00:00
//if not same file system - could be removable drive
2019-12-10 13:41:49 +00:00
if(!compare_filesystem_id(path, parent_path))
2019-12-10 13:10:47 +00:00
{
2019-12-19 15:27:48 +00:00
//free space
2019-12-19 16:05:23 +00:00
boost::filesystem::space_info si = boost::filesystem::space(path);
2019-12-19 15:27:48 +00:00
//std::cout << "Free space: " << fs_si.free << "Available space: " << fs_si.available << " " << path << '\n';
2019-12-19 16:05:23 +00:00
if(si.available != 0)
2019-12-10 13:10:47 +00:00
{
2019-12-19 15:27:48 +00:00
//user id
struct stat buf;
stat(path.c_str(), &buf);
uid_t uid = buf.st_uid;
std::string username(std::getenv("USER"));
struct passwd *pw = getpwuid(uid);
if (pw != 0 && pw->pw_name == username)
m_current_drives.push_back(DriveData(boost::filesystem::basename(boost::filesystem::path(path)), path));
2019-12-10 13:10:47 +00:00
}
2019-12-19 15:27:48 +00:00
2019-12-10 13:10:47 +00:00
}
}
2019-11-28 15:35:22 +00:00
bool RemovableDriveManager::compare_filesystem_id(const std::string &path_a, const std::string &path_b)
{
struct stat buf;
stat(path_a.c_str() ,&buf);
dev_t id_a = buf.st_dev;
stat(path_b.c_str() ,&buf);
dev_t id_b = buf.st_dev;
return id_a == id_b;
}
2019-11-27 10:33:36 +00:00
void RemovableDriveManager::eject_drive(const std::string &path)
2019-11-26 14:52:18 +00:00
{
2019-11-27 10:33:36 +00:00
if (m_current_drives.empty())
2019-11-26 14:52:18 +00:00
return;
2019-11-27 10:33:36 +00:00
for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
2019-11-26 14:52:18 +00:00
{
if((*it).path == path)
{
2019-12-04 12:10:08 +00:00
std::string correct_path(path);
for (size_t i = 0; i < correct_path.size(); ++i)
{
if(correct_path[i]==' ')
{
2019-12-04 12:18:08 +00:00
correct_path = correct_path.insert(i,1,'\\');
2019-12-04 12:13:18 +00:00
i++;
2019-12-04 12:10:08 +00:00
}
}
2019-12-04 12:21:41 +00:00
std::cout<<"Ejecting "<<(*it).name<<" from "<< correct_path<<"\n";
2019-12-13 10:52:08 +00:00
// there is no usable command in c++ so terminal command is used instead
// but neither triggers "succesful safe removal messege"
2019-12-04 12:30:25 +00:00
std::string command = "";
#if __APPLE__
2019-12-17 12:08:17 +00:00
//m_rdmmm->eject_device(path);
2019-12-04 12:30:25 +00:00
command = "diskutil unmount ";
#else
command = "umount ";
#endif
2019-12-04 12:18:08 +00:00
command += correct_path;
2019-12-03 09:09:53 +00:00
int err = system(command.c_str());
if(err)
2019-11-26 14:52:18 +00:00
{
2019-12-03 09:09:53 +00:00
std::cerr<<"Ejecting failed\n";
return;
2019-11-26 14:52:18 +00:00
}
2019-12-17 12:08:17 +00:00
m_did_eject = true;
2019-11-27 10:33:36 +00:00
m_current_drives.erase(it);
2019-12-03 09:09:53 +00:00
2019-11-26 14:52:18 +00:00
break;
}
}
}
2019-11-27 13:30:10 +00:00
bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path)
{
if (m_current_drives.empty())
return false;
2019-12-18 14:40:48 +00:00
std::size_t found = path.find_last_of("/");
std::string new_path = path.substr(0,found);
2019-11-27 13:30:10 +00:00
for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
{
2019-12-18 14:40:48 +00:00
if(compare_filesystem_id(new_path, (*it).path))
2019-11-27 13:30:10 +00:00
return true;
}
return false;
}
2019-12-05 13:07:02 +00:00
std::string RemovableDriveManager::get_drive_from_path(const std::string& path)
{
std::size_t found = path.find_last_of("/");
std::string new_path = path.substr(0, found);
2019-12-05 13:07:02 +00:00
//check if same filesystem
for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
{
if (compare_filesystem_id(new_path, (*it).path))
2019-12-05 13:07:02 +00:00
return (*it).path;
}
return "";
}
2019-11-26 14:52:18 +00:00
#endif
2019-12-11 10:00:47 +00:00
RemovableDriveManager::RemovableDriveManager():
m_drives_count(0),
m_last_update(0),
2019-12-13 17:02:25 +00:00
m_last_save_path(""),
m_last_save_name(""),
2019-12-16 16:15:27 +00:00
m_last_save_path_verified(false),
m_is_writing(false),
m_did_eject(false),
m_plater_ready_to_slice(true)
2019-12-11 10:00:47 +00:00
#if __APPLE__
2019-12-11 11:28:51 +00:00
, m_rdmmm(new RDMMMWrapper())
2019-12-11 10:00:47 +00:00
#endif
{}
RemovableDriveManager::~RemovableDriveManager()
{
#if __APPLE__
delete m_rdmmm;
#endif
}
void RemovableDriveManager::init()
2019-11-26 14:52:18 +00:00
{
2019-12-11 13:53:28 +00:00
//add_callback([](void) { RemovableDriveManager::get_instance().print(); });
2019-11-28 12:38:08 +00:00
#if _WIN32
2019-12-12 09:48:33 +00:00
//register_window();
2019-12-10 10:17:12 +00:00
#elif __APPLE__
2019-12-11 10:00:47 +00:00
m_rdmmm->register_window();
2019-11-28 12:38:08 +00:00
#endif
2019-12-16 13:06:25 +00:00
update(0, true);
}
2019-12-12 13:56:30 +00:00
bool RemovableDriveManager::update(const long time,const bool check)
{
2019-11-27 14:47:37 +00:00
if(time != 0) //time = 0 is forced update
{
2019-12-04 14:27:33 +00:00
long diff = m_last_update - time;
2019-11-27 14:47:37 +00:00
if(diff <= -2)
{
2019-12-04 14:27:33 +00:00
m_last_update = time;
2019-11-27 14:47:37 +00:00
}else
{
return false; // return value shouldnt matter if update didnt run
}
}
2019-11-27 10:33:36 +00:00
search_for_drives();
2019-12-19 13:19:41 +00:00
if (m_drives_count != m_current_drives.size())
{
if (check)check_and_notify();
m_drives_count = m_current_drives.size();
}
2019-11-27 10:33:36 +00:00
return !m_current_drives.empty();
2019-11-26 14:52:18 +00:00
}
2019-11-27 10:33:36 +00:00
bool RemovableDriveManager::is_drive_mounted(const std::string &path)
2019-11-26 14:52:18 +00:00
{
2019-11-27 10:33:36 +00:00
for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
2019-11-26 14:52:18 +00:00
{
if ((*it).path == path)
{
return true;
}
}
return false;
}
2019-12-11 13:53:28 +00:00
std::string RemovableDriveManager::get_drive_path()
{
if (m_current_drives.size() == 0)
{
reset_last_save_path();
return "";
}
2019-12-16 16:15:27 +00:00
if (m_last_save_path_verified)
2019-12-11 13:53:28 +00:00
return m_last_save_path;
return m_current_drives.back().path;
}
std::string RemovableDriveManager::get_last_save_path()
2019-11-26 13:19:29 +00:00
{
2019-12-16 16:15:27 +00:00
if (!m_last_save_path_verified)
return "";
2019-12-11 11:28:51 +00:00
return m_last_save_path;
2019-11-26 13:19:29 +00:00
}
2019-12-13 17:02:25 +00:00
std::string RemovableDriveManager::get_last_save_name()
{
return m_last_save_name;
}
2019-11-27 10:33:36 +00:00
std::vector<DriveData> RemovableDriveManager::get_all_drives()
2019-11-26 13:19:29 +00:00
{
2019-11-27 10:33:36 +00:00
return m_current_drives;
2019-11-26 13:19:29 +00:00
}
2019-11-28 12:38:08 +00:00
void RemovableDriveManager::check_and_notify()
{
if(m_drive_count_changed_callback)
{
m_drive_count_changed_callback(m_plater_ready_to_slice);
}
2019-12-19 13:19:41 +00:00
if(m_callbacks.size() != 0 && m_drives_count > m_current_drives.size() && m_last_save_path_verified && !is_drive_mounted(m_last_save_path))
2019-11-28 12:38:08 +00:00
{
2019-12-19 13:19:41 +00:00
for (auto it = m_callbacks.begin(); it != m_callbacks.end(); ++it)
2019-11-28 12:38:08 +00:00
{
2019-12-19 13:19:41 +00:00
(*it)();
2019-11-28 12:38:08 +00:00
}
}
}
void RemovableDriveManager::add_remove_callback(std::function<void()> callback)
2019-11-28 12:38:08 +00:00
{
m_callbacks.push_back(callback);
}
void RemovableDriveManager::erase_callbacks()
2019-12-06 12:21:44 +00:00
{
m_callbacks.clear();
}
void RemovableDriveManager::set_drive_count_changed_callback(std::function<void(const bool)> callback)
{
m_drive_count_changed_callback = callback;
}
void RemovableDriveManager::set_plater_ready_to_slice(bool b)
{
m_plater_ready_to_slice = b;
}
2019-12-05 13:07:02 +00:00
void RemovableDriveManager::set_last_save_path(const std::string& path)
{
2019-12-18 08:36:26 +00:00
m_last_save_path_verified = false;
2019-12-16 16:15:27 +00:00
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 != "")
2019-12-05 13:07:02 +00:00
{
2019-12-16 16:15:27 +00:00
m_last_save_path_verified = true;
2019-12-05 13:07:02 +00:00
m_last_save_path = last_drive;
2019-12-13 17:02:25 +00:00
m_last_save_name = get_drive_name(last_drive);
2019-12-19 13:19:41 +00:00
}else
{
reset_last_save_path();
2019-12-05 13:07:02 +00:00
}
}
2019-12-13 17:02:25 +00:00
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 "";
}
2019-12-05 13:07:02 +00:00
bool RemovableDriveManager::is_last_drive_removed()
{
2019-12-12 09:48:33 +00:00
//std::cout<<"is last: "<<m_last_save_path;
//m_drives_count = m_current_drives.size();
2019-12-16 16:15:27 +00:00
if(!m_last_save_path_verified)
2019-12-05 13:07:02 +00:00
{
2019-12-12 09:48:33 +00:00
//std::cout<<"\n";
2019-12-05 13:07:02 +00:00
return true;
}
2019-12-11 11:28:51 +00:00
bool r = !is_drive_mounted(m_last_save_path);
if (r) reset_last_save_path();
2019-12-12 09:48:33 +00:00
//std::cout<<" "<< r <<"\n";
2019-12-11 11:28:51 +00:00
return r;
2019-12-05 13:07:02 +00:00
}
2019-12-05 15:22:54 +00:00
bool RemovableDriveManager::is_last_drive_removed_with_update(const long time)
{
2019-12-11 11:28:51 +00:00
update(time, false);
2019-12-05 15:22:54 +00:00
return is_last_drive_removed();
}
2019-12-05 13:07:02 +00:00
void RemovableDriveManager::reset_last_save_path()
{
2019-12-16 16:15:27 +00:00
m_last_save_path_verified = false;
2019-12-05 13:07:02 +00:00
m_last_save_path = "";
2019-12-13 17:02:25 +00:00
m_last_save_name = "";
}
void RemovableDriveManager::set_is_writing(const bool b)
{
m_is_writing = b;
if (b)
{
m_did_eject = false;
}
2019-12-13 17:02:25 +00:00
}
bool RemovableDriveManager::get_is_writing()
{
return m_is_writing;
2019-12-05 13:07:02 +00:00
}
bool RemovableDriveManager::get_did_eject()
{
return m_did_eject;
}
2019-12-18 09:08:17 +00:00
void RemovableDriveManager::set_did_eject(const bool b)
{
m_did_eject = b;
}
size_t RemovableDriveManager::get_drives_count()
{
return m_current_drives.size();
}
2019-12-12 13:56:30 +00:00
}}//namespace Slicer::Gui