Merge branch 'dk_remote_devices'
This commit is contained in:
commit
5e91bcc91c
145
resources/icons/export_to_sd.svg
Normal file
145
resources/icons/export_to_sd.svg
Normal file
@ -0,0 +1,145 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="svg8"
|
||||
version="1.1"
|
||||
viewBox="0 0 210 297"
|
||||
height="297mm"
|
||||
width="210mm">
|
||||
<defs
|
||||
id="defs2">
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath3733">
|
||||
<path
|
||||
d="M 0,800 H 800 V 0 H 0 Z"
|
||||
id="path3731" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1">
|
||||
<g
|
||||
id="g3721"
|
||||
transform="matrix(0.35277777,0,0,-0.35277777,-27.74952,290.88146)">
|
||||
<path
|
||||
d="M 381.663,302.607 H 558.791 V 65.846 H 381.663 Z"
|
||||
style="fill:#d8d8db;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3723" />
|
||||
<path
|
||||
d="m 470.227,302.607 h 95.411 V 65.846 h -95.411 z"
|
||||
style="fill:#f7f7f8;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3725" />
|
||||
<g
|
||||
id="g3727">
|
||||
<g
|
||||
id="g3729"
|
||||
clip-path="url(#clipPath3733)">
|
||||
<g
|
||||
id="g3735"
|
||||
transform="translate(380.7793,225.1963)">
|
||||
<path
|
||||
d="m 0,0 h 174.037 c 39.032,0 70.675,31.643 70.675,70.675 v 372.92 c 0,39.033 -31.643,70.675 -70.675,70.675 H 0 c -39.033,0 -70.675,-31.642 -70.675,-70.675 V 70.675 C -70.675,31.643 -39.033,0 0,0"
|
||||
style="fill:#e96700;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3737" />
|
||||
</g>
|
||||
<g
|
||||
id="g3739"
|
||||
transform="translate(377.0244,168.7666)">
|
||||
<path
|
||||
d="m 0,0 h -237.865 c -8.782,0 -15.902,7.12 -15.902,15.902 v 365.743 c 0,8.782 7.12,15.901 15.902,15.901 H 28.933 c 8.782,0 15.902,-7.119 15.902,-15.901 V 56.43 C 38.907,48.507 9.055,8.503 0,0"
|
||||
style="fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3741" />
|
||||
</g>
|
||||
<g
|
||||
id="g3743"
|
||||
transform="translate(421.8594,225.1963)">
|
||||
<path
|
||||
d="M 0,0 C -7.399,-10.049 -35.78,-47.927 -44.835,-56.43 H -282.7"
|
||||
style="fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3745" />
|
||||
</g>
|
||||
<g
|
||||
id="g3747"
|
||||
transform="translate(421.8594,225.1963)">
|
||||
<path
|
||||
d="M 0,0 C -5.876,-7.899 -35.78,-47.927 -44.835,-56.43"
|
||||
style="fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3749" />
|
||||
</g>
|
||||
<g
|
||||
id="g3751"
|
||||
transform="translate(333.957,198.1406)">
|
||||
<path
|
||||
d="m 0,0 h -22.969 c -2.196,0 -3.976,1.78 -3.976,3.976 v 81.276 c 0,2.195 1.78,3.976 3.976,3.976 H 0 c 2.196,0 3.976,-1.781 3.976,-3.976 V 3.976 C 3.976,1.78 2.196,0 0,0"
|
||||
style="fill:#efee86;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3753" />
|
||||
</g>
|
||||
<g
|
||||
id="g3755"
|
||||
transform="translate(297.957,198.1406)">
|
||||
<path
|
||||
d="m 0,0 h -22.969 c -2.196,0 -3.976,1.78 -3.976,3.976 v 81.276 c 0,2.195 1.78,3.976 3.976,3.976 H 0 c 2.196,0 3.976,-1.781 3.976,-3.976 V 3.976 C 3.976,1.78 2.196,0 0,0"
|
||||
style="fill:#efee86;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3757" />
|
||||
</g>
|
||||
<g
|
||||
id="g3759"
|
||||
transform="translate(261.957,198.1406)">
|
||||
<path
|
||||
d="m 0,0 h -22.969 c -2.196,0 -3.976,1.78 -3.976,3.976 v 81.276 c 0,2.195 1.78,3.976 3.976,3.976 H 0 c 2.196,0 3.976,-1.781 3.976,-3.976 V 3.976 C 3.976,1.78 2.196,0 0,0"
|
||||
style="fill:#efee86;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3761" />
|
||||
</g>
|
||||
<g
|
||||
id="g3763"
|
||||
transform="translate(225.957,198.1406)">
|
||||
<path
|
||||
d="m 0,0 h -22.969 c -2.196,0 -3.976,1.78 -3.976,3.976 v 81.276 c 0,2.195 1.78,3.976 3.976,3.976 H 0 c 2.196,0 3.976,-1.781 3.976,-3.976 V 3.976 C 3.976,1.78 2.196,0 0,0"
|
||||
style="fill:#efee86;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3765" />
|
||||
</g>
|
||||
<g
|
||||
id="g3767"
|
||||
transform="translate(189.957,198.1406)">
|
||||
<path
|
||||
d="m 0,0 h -22.969 c -2.196,0 -3.976,1.78 -3.976,3.976 v 81.276 c 0,2.195 1.78,3.976 3.976,3.976 H 0 c 2.196,0 3.976,-1.781 3.976,-3.976 V 3.976 C 3.976,1.78 2.196,0 0,0"
|
||||
style="fill:#efee86;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3769" />
|
||||
</g>
|
||||
<g
|
||||
id="g3771"
|
||||
transform="translate(369.2207,225.1963)">
|
||||
<path
|
||||
d="m 0,0 h -22.969 c -2.196,0 -3.976,1.78 -3.976,3.976 v 54.22 c 0,2.196 1.78,3.976 3.976,3.976 H 0 c 2.196,0 3.976,-1.78 3.976,-3.976 V 3.976 C 3.976,1.78 2.196,0 0,0"
|
||||
style="fill:#efee86;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3773" />
|
||||
</g>
|
||||
<path
|
||||
d="m 450.019,104.056 h -50.577 v 33.128 h 50.577 z"
|
||||
style="fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3775" />
|
||||
<path
|
||||
d="m 543.221,104.056 h -50.576 v 33.128 h 50.576 z"
|
||||
style="fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3777" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.8 KiB |
@ -78,6 +78,9 @@ void AppConfig::set_defaults()
|
||||
if (get("remember_output_path").empty())
|
||||
set("remember_output_path", "1");
|
||||
|
||||
if (get("remember_output_path_removable").empty())
|
||||
set("remember_output_path_removable", "1");
|
||||
|
||||
if (get("use_custom_toolbar_size").empty())
|
||||
set("use_custom_toolbar_size", "0");
|
||||
|
||||
@ -388,7 +391,7 @@ void AppConfig::update_skein_dir(const std::string &dir)
|
||||
{
|
||||
this->set("recent", "skein_directory", dir);
|
||||
}
|
||||
|
||||
/*
|
||||
std::string AppConfig::get_last_output_dir(const std::string &alt) const
|
||||
{
|
||||
|
||||
@ -406,6 +409,26 @@ void AppConfig::update_last_output_dir(const std::string &dir)
|
||||
{
|
||||
this->set("", "last_output_path", dir);
|
||||
}
|
||||
*/
|
||||
std::string AppConfig::get_last_output_dir(const std::string& alt, const bool removable) const
|
||||
{
|
||||
std::string s1 = (removable ? "last_output_path_removable" : "last_output_path");
|
||||
std::string s2 = (removable ? "remember_output_path_removable" : "remember_output_path");
|
||||
const auto it = m_storage.find("");
|
||||
if (it != m_storage.end()) {
|
||||
const auto it2 = it->second.find(s1);
|
||||
const auto it3 = it->second.find(s2);
|
||||
if (it2 != it->second.end() && it3 != it->second.end() && !it2->second.empty() && it3->second == "1")
|
||||
return it2->second;
|
||||
}
|
||||
return alt;
|
||||
}
|
||||
|
||||
void AppConfig::update_last_output_dir(const std::string& dir, const bool removable)
|
||||
{
|
||||
this->set("", (removable ? "last_output_path_removable" : "last_output_path"), dir);
|
||||
}
|
||||
|
||||
|
||||
void AppConfig::reset_selections()
|
||||
{
|
||||
|
@ -102,8 +102,10 @@ public:
|
||||
void update_config_dir(const std::string &dir);
|
||||
void update_skein_dir(const std::string &dir);
|
||||
|
||||
std::string get_last_output_dir(const std::string &alt) const;
|
||||
void update_last_output_dir(const std::string &dir);
|
||||
//std::string get_last_output_dir(const std::string &alt) const;
|
||||
//void update_last_output_dir(const std::string &dir);
|
||||
std::string get_last_output_dir(const std::string& alt, const bool removable = false) const;
|
||||
void update_last_output_dir(const std::string &dir, const bool removable = false);
|
||||
|
||||
// reset the current print / filament / printer selections, so that
|
||||
// the PresetBundle::load_selections(const AppConfig &config) call will select
|
||||
|
@ -701,6 +701,7 @@ struct Sidebar::priv
|
||||
wxButton *btn_reslice;
|
||||
ScalableButton *btn_send_gcode;
|
||||
ScalableButton *btn_remove_device;
|
||||
ScalableButton* btn_export_gcode_removable; //exports to removable drives (appears only if removable drive is connected)
|
||||
|
||||
priv(Plater *plater) : plater(plater) {}
|
||||
~priv();
|
||||
@ -866,6 +867,7 @@ Sidebar::Sidebar(Plater *parent)
|
||||
|
||||
init_scalable_btn(&p->btn_send_gcode , "export_gcode", _(L("Send to printer")));
|
||||
init_scalable_btn(&p->btn_remove_device, "cross" , _(L("Remove device")));
|
||||
init_scalable_btn(&p->btn_export_gcode_removable, "export_to_sd", _(L("Export to SD card/ USB thumb drive")));
|
||||
|
||||
// regular buttons "Slice now" and "Export G-code"
|
||||
|
||||
@ -886,7 +888,9 @@ 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);
|
||||
complect_btns_sizer->Add(p->btn_export_gcode_removable);
|
||||
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);
|
||||
@ -897,7 +901,7 @@ Sidebar::Sidebar(Plater *parent)
|
||||
SetSizer(sizer);
|
||||
|
||||
// Events
|
||||
p->btn_export_gcode->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->export_gcode(); });
|
||||
p->btn_export_gcode->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->export_gcode(false); });
|
||||
p->btn_reslice->Bind(wxEVT_BUTTON, [this](wxCommandEvent&)
|
||||
{
|
||||
const bool export_gcode_after_slicing = wxGetKeyState(WXK_SHIFT);
|
||||
@ -909,6 +913,7 @@ Sidebar::Sidebar(Plater *parent)
|
||||
});
|
||||
p->btn_send_gcode->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->send_gcode(); });
|
||||
p->btn_remove_device->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->eject_drive(); });
|
||||
p->btn_export_gcode_removable->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->export_gcode(true); });
|
||||
}
|
||||
|
||||
Sidebar::~Sidebar() {}
|
||||
@ -1056,6 +1061,7 @@ void Sidebar::msw_rescale()
|
||||
|
||||
p->btn_send_gcode->msw_rescale();
|
||||
p->btn_remove_device->msw_rescale();
|
||||
p->btn_export_gcode_removable->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));
|
||||
@ -1289,12 +1295,14 @@ void Sidebar::enable_buttons(bool enable)
|
||||
p->btn_export_gcode->Enable(enable);
|
||||
p->btn_send_gcode->Enable(enable);
|
||||
p->btn_remove_device->Enable(enable);
|
||||
p->btn_export_gcode_removable->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_remove_device->Show(show); }
|
||||
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_remove_device->Show(show); }
|
||||
bool Sidebar::show_export_removable(bool show)const { return p->btn_export_gcode_removable->Show(show); }
|
||||
|
||||
bool Sidebar::is_multifilament()
|
||||
{
|
||||
@ -2192,6 +2200,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||
|
||||
// Initialize the Undo / Redo stack with a first snapshot.
|
||||
this->take_snapshot(_(L("New Project")));
|
||||
|
||||
//void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const
|
||||
RemovableDriveManager::get_instance().set_drive_count_changed_callback(std::bind(&Plater::priv::show_action_buttons, this, std::placeholders::_1));
|
||||
}
|
||||
|
||||
Plater::priv::~priv()
|
||||
@ -3596,12 +3607,8 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt)
|
||||
|
||||
if(!canceled && RemovableDriveManager::get_instance().get_is_writing())
|
||||
{
|
||||
//if (!RemovableDriveManager::get_instance().is_last_drive_removed())
|
||||
//{
|
||||
RemovableDriveManager::get_instance().set_is_writing(false);
|
||||
show_action_buttons(false);
|
||||
//}
|
||||
|
||||
RemovableDriveManager::get_instance().set_is_writing(false);
|
||||
show_action_buttons(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4156,18 +4163,21 @@ void Plater::priv::update_object_menu()
|
||||
|
||||
void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const
|
||||
{
|
||||
RemovableDriveManager::get_instance().set_plater_ready_to_slice(is_ready_to_slice);
|
||||
wxWindowUpdateLocker noUpdater(sidebar);
|
||||
const auto prin_host_opt = config->option<ConfigOptionString>("print_host");
|
||||
const bool send_gcode_shown = prin_host_opt != nullptr && !prin_host_opt->value.empty();
|
||||
|
||||
bool disconnect_shown = !RemovableDriveManager::get_instance().is_last_drive_removed() ; // #dk_FIXME
|
||||
bool disconnect_shown = !RemovableDriveManager::get_instance().is_last_drive_removed();
|
||||
bool export_removable_shown = RemovableDriveManager::get_instance().get_drives_count() > 0;
|
||||
// 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_disconnect(disconnect_shown))
|
||||
if (sidebar->show_reslice(false) |
|
||||
sidebar->show_export(true) |
|
||||
sidebar->show_send(send_gcode_shown) |
|
||||
sidebar->show_export_removable(export_removable_shown) |
|
||||
sidebar->show_disconnect(disconnect_shown))
|
||||
sidebar->Layout();
|
||||
}
|
||||
else
|
||||
@ -4175,6 +4185,7 @@ void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const
|
||||
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_export_removable(export_removable_shown && !is_ready_to_slice) |
|
||||
sidebar->show_disconnect(disconnect_shown && !is_ready_to_slice))
|
||||
sidebar->Layout();
|
||||
}
|
||||
@ -4684,7 +4695,7 @@ void Plater::cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_uppe
|
||||
}
|
||||
}
|
||||
|
||||
void Plater::export_gcode()
|
||||
void Plater::export_gcode(bool prefer_removable)
|
||||
{
|
||||
if (p->model.objects.empty())
|
||||
return;
|
||||
@ -4706,11 +4717,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());
|
||||
if (GUI::RemovableDriveManager::get_instance().update())
|
||||
bool removable_drives_connected = GUI::RemovableDriveManager::get_instance().update();
|
||||
if(prefer_removable)
|
||||
{
|
||||
if (!RemovableDriveManager::get_instance().is_path_on_removable_drive(start_dir))
|
||||
if(removable_drives_connected)
|
||||
{
|
||||
start_dir = RemovableDriveManager::get_instance().get_drive_path();
|
||||
auto start_dir_removable = wxGetApp().app_config->get_last_output_dir(default_output_file.parent_path().string(), true);
|
||||
if (RemovableDriveManager::get_instance().is_path_on_removable_drive(start_dir_removable))
|
||||
{
|
||||
start_dir = start_dir_removable;
|
||||
}else
|
||||
{
|
||||
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:")),
|
||||
@ -4723,7 +4742,7 @@ void Plater::export_gcode()
|
||||
fs::path output_path;
|
||||
if (dlg.ShowModal() == wxID_OK) {
|
||||
fs::path path = into_path(dlg.GetPath());
|
||||
wxGetApp().app_config->update_last_output_dir(path.parent_path().string());
|
||||
wxGetApp().app_config->update_last_output_dir(path.parent_path().string(), RemovableDriveManager::get_instance().is_path_on_removable_drive(path.parent_path().string()));
|
||||
output_path = std::move(path);
|
||||
}
|
||||
if (! output_path.empty())
|
||||
@ -4739,7 +4758,7 @@ void Plater::export_gcode()
|
||||
{
|
||||
RemovableDriveManager::get_instance().set_is_writing(true);
|
||||
RemovableDriveManager::get_instance().erase_callbacks();
|
||||
RemovableDriveManager::get_instance().add_callback(std::bind(&Plater::drive_ejected_callback, this));
|
||||
RemovableDriveManager::get_instance().add_remove_callback(std::bind(&Plater::drive_ejected_callback, this));
|
||||
}
|
||||
|
||||
}
|
||||
@ -5041,8 +5060,8 @@ 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_remove_callback(std::bind(&Plater::drive_ejected_callback, this));
|
||||
RemovableDriveManager::get_instance().eject_drive(RemovableDriveManager::get_instance().get_last_save_path());
|
||||
|
||||
}
|
||||
@ -5051,7 +5070,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.";
|
||||
wxString message = "Unmounting successful. The device " + RemovableDriveManager::get_instance().get_ejected_name() + "(" + RemovableDriveManager::get_instance().get_ejected_path() + ")" + " can now be safely removed from the computer.";
|
||||
wxMessageBox(message);
|
||||
}
|
||||
p->show_action_buttons(false);
|
||||
|
@ -120,6 +120,7 @@ public:
|
||||
bool show_export(bool show) const;
|
||||
bool show_send(bool show) const;
|
||||
bool show_disconnect(bool show)const;
|
||||
bool show_export_removable(bool show) const;
|
||||
bool is_multifilament();
|
||||
void update_mode();
|
||||
|
||||
@ -186,7 +187,7 @@ public:
|
||||
|
||||
void cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_upper = true, bool keep_lower = true, bool rotate_lower = false);
|
||||
|
||||
void export_gcode();
|
||||
void export_gcode(bool prefer_removable = true);
|
||||
void export_stl(bool extended = false, bool selection_only = false);
|
||||
void export_amf();
|
||||
void export_3mf(const boost::filesystem::path& output_path = boost::filesystem::path());
|
||||
|
@ -109,6 +109,8 @@ void RemovableDriveManager::eject_drive(const std::string &path)
|
||||
CloseHandle(handle);
|
||||
m_did_eject = true;
|
||||
m_current_drives.erase(it);
|
||||
m_ejected_path = m_last_save_path;
|
||||
m_ejected_name = m_last_save_name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -239,35 +241,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";
|
||||
//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) {
|
||||
break;
|
||||
}
|
||||
path = entry->pw_name;
|
||||
pp = path;
|
||||
//search /media/USERNAME/* folder
|
||||
pp = "/media/"+pp;
|
||||
path = "/media/" + path + "/*";
|
||||
search_path(path, pp);
|
||||
|
||||
//search /run/media/USERNAME/* folder
|
||||
path = "/run" + path;
|
||||
pp = "/run"+pp;
|
||||
search_path(path, pp);
|
||||
}
|
||||
endpwent();
|
||||
}else
|
||||
*/
|
||||
{
|
||||
//search /media/USERNAME/* folder
|
||||
pp = "/media/"+pp;
|
||||
@ -310,7 +287,6 @@ void RemovableDriveManager::inspect_file(const std::string &path, const std::str
|
||||
{
|
||||
//free space
|
||||
boost::filesystem::space_info si = boost::filesystem::space(path);
|
||||
//std::cout << "Free space: " << fs_si.free << "Available space: " << fs_si.available << " " << path << '\n';
|
||||
if(si.available != 0)
|
||||
{
|
||||
//user id
|
||||
@ -353,7 +329,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";
|
||||
// there is no usable command in c++ so terminal command is used instead
|
||||
// but neither triggers "succesful safe removal messege"
|
||||
std::string command = "";
|
||||
@ -373,7 +349,8 @@ void RemovableDriveManager::eject_drive(const std::string &path)
|
||||
|
||||
m_did_eject = true;
|
||||
m_current_drives.erase(it);
|
||||
|
||||
m_ejected_path = m_last_save_path;
|
||||
m_ejected_name = m_last_save_name;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -385,7 +362,7 @@ 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);
|
||||
std::string new_path = found == path.size() - 1 ? path.substr(0, found) : path;
|
||||
for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
|
||||
{
|
||||
if(compare_filesystem_id(new_path, (*it).path))
|
||||
@ -396,7 +373,7 @@ bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path)
|
||||
std::string RemovableDriveManager::get_drive_from_path(const std::string& path)
|
||||
{
|
||||
std::size_t found = path.find_last_of("/");
|
||||
std::string new_path = path.substr(0, found);
|
||||
std::string new_path = found == path.size() - 1 ? path.substr(0, found) : path;
|
||||
//check if same filesystem
|
||||
for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
|
||||
{
|
||||
@ -414,7 +391,10 @@ RemovableDriveManager::RemovableDriveManager():
|
||||
m_last_save_name(""),
|
||||
m_last_save_path_verified(false),
|
||||
m_is_writing(false),
|
||||
m_did_eject(false)
|
||||
m_did_eject(false),
|
||||
m_plater_ready_to_slice(true),
|
||||
m_ejected_path(""),
|
||||
m_ejected_name("")
|
||||
#if __APPLE__
|
||||
, m_rdmmm(new RDMMMWrapper())
|
||||
#endif
|
||||
@ -451,7 +431,10 @@ bool RemovableDriveManager::update(const long time,const bool check)
|
||||
search_for_drives();
|
||||
if (m_drives_count != m_current_drives.size())
|
||||
{
|
||||
if (check)check_and_notify();
|
||||
if (check)
|
||||
{
|
||||
check_and_notify();
|
||||
}
|
||||
m_drives_count = m_current_drives.size();
|
||||
}
|
||||
return !m_current_drives.empty();
|
||||
@ -495,7 +478,11 @@ std::vector<DriveData> RemovableDriveManager::get_all_drives()
|
||||
}
|
||||
void RemovableDriveManager::check_and_notify()
|
||||
{
|
||||
if(m_callbacks.size() != 0 && m_drives_count > m_current_drives.size() && m_last_save_path_verified && !is_drive_mounted(m_last_save_path))
|
||||
if(m_drive_count_changed_callback)
|
||||
{
|
||||
m_drive_count_changed_callback(m_plater_ready_to_slice);
|
||||
}
|
||||
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)
|
||||
{
|
||||
@ -503,18 +490,35 @@ void RemovableDriveManager::check_and_notify()
|
||||
}
|
||||
}
|
||||
}
|
||||
void RemovableDriveManager::add_callback(std::function<void()> callback)
|
||||
void RemovableDriveManager::add_remove_callback(std::function<void()> callback)
|
||||
{
|
||||
m_callbacks.push_back(callback);
|
||||
}
|
||||
void RemovableDriveManager::erase_callbacks()
|
||||
void RemovableDriveManager::erase_callbacks()
|
||||
{
|
||||
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;
|
||||
}
|
||||
void RemovableDriveManager::set_last_save_path(const std::string& path)
|
||||
{
|
||||
m_last_save_path_verified = false;
|
||||
m_last_save_path = path;
|
||||
if(m_last_save_path_verified)// if old path is on drive
|
||||
{
|
||||
if(get_drive_from_path(path) != "") //and new is too, rewrite the path
|
||||
{
|
||||
m_last_save_path_verified = false;
|
||||
m_last_save_path = path;
|
||||
}//else do nothing
|
||||
}else
|
||||
{
|
||||
m_last_save_path = path;
|
||||
}
|
||||
}
|
||||
void RemovableDriveManager::verify_last_save_path()
|
||||
{
|
||||
@ -544,16 +548,15 @@ std::string RemovableDriveManager::get_drive_name(const std::string& path)
|
||||
}
|
||||
bool RemovableDriveManager::is_last_drive_removed()
|
||||
{
|
||||
//std::cout<<"is last: "<<m_last_save_path;
|
||||
//m_drives_count = m_current_drives.size();
|
||||
if(!m_last_save_path_verified)
|
||||
{
|
||||
//std::cout<<"\n";
|
||||
return true;
|
||||
}
|
||||
bool r = !is_drive_mounted(m_last_save_path);
|
||||
if (r) reset_last_save_path();
|
||||
//std::cout<<" "<< r <<"\n";
|
||||
if (r)
|
||||
{
|
||||
reset_last_save_path();
|
||||
}
|
||||
return r;
|
||||
}
|
||||
bool RemovableDriveManager::is_last_drive_removed_with_update(const long time)
|
||||
@ -587,4 +590,16 @@ void RemovableDriveManager::set_did_eject(const bool b)
|
||||
{
|
||||
m_did_eject = b;
|
||||
}
|
||||
size_t RemovableDriveManager::get_drives_count()
|
||||
{
|
||||
return m_current_drives.size();
|
||||
}
|
||||
std::string RemovableDriveManager::get_ejected_path()
|
||||
{
|
||||
return m_ejected_path;
|
||||
}
|
||||
std::string RemovableDriveManager::get_ejected_name()
|
||||
{
|
||||
return m_ejected_name;
|
||||
}
|
||||
}}//namespace Slicer::Gui
|
||||
|
@ -45,9 +45,13 @@ public:
|
||||
std::vector<DriveData> get_all_drives();
|
||||
bool is_path_on_removable_drive(const std::string &path);
|
||||
// callback will notify only if device with last save path was removed
|
||||
void add_callback(std::function<void()> callback);
|
||||
// erases all callbacks added by add_callback()
|
||||
void add_remove_callback(std::function<void()> callback);
|
||||
// erases all remove callbacks added by add_remove_callback()
|
||||
void erase_callbacks();
|
||||
//drive_count_changed callback is called on every added or removed device
|
||||
void set_drive_count_changed_callback(std::function<void(const bool)> callback);
|
||||
//thi serves to set correct value for drive_count_changed callback
|
||||
void set_plater_ready_to_slice(bool b);
|
||||
// marks one of the eveices in vector as last used
|
||||
void set_last_save_path(const std::string &path);
|
||||
void verify_last_save_path();
|
||||
@ -59,6 +63,9 @@ public:
|
||||
bool get_did_eject();
|
||||
void set_did_eject(const bool b);
|
||||
std::string get_drive_name(const std::string& path);
|
||||
size_t get_drives_count();
|
||||
std::string get_ejected_path();
|
||||
std::string get_ejected_name();
|
||||
private:
|
||||
RemovableDriveManager();
|
||||
void search_for_drives();
|
||||
@ -70,6 +77,7 @@ private:
|
||||
|
||||
std::vector<DriveData> m_current_drives;
|
||||
std::vector<std::function<void()>> m_callbacks;
|
||||
std::function<void(const bool)> m_drive_count_changed_callback;
|
||||
size_t m_drives_count;
|
||||
long m_last_update;
|
||||
std::string m_last_save_path;
|
||||
@ -77,6 +85,9 @@ private:
|
||||
std::string m_last_save_name;
|
||||
bool m_is_writing;//on device
|
||||
bool m_did_eject;
|
||||
bool m_plater_ready_to_slice;
|
||||
std::string m_ejected_path;
|
||||
std::string m_ejected_name;
|
||||
#if _WIN32
|
||||
//registers for notifications by creating invisible window
|
||||
void register_window();
|
||||
|
Loading…
Reference in New Issue
Block a user