mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-11 16:57:53 -06:00
Refactoring of RemovableDriveManager
1) On Windows and Linux, polling of removable drives is done at a background thread, not at a UI thread. 2) On OSX, there is no polling, but a OS notification callback. 3) Refactored for clarity of the RemovableDriveManager interface.
This commit is contained in:
parent
fa00180170
commit
baad542d15
11 changed files with 640 additions and 753 deletions
|
@ -1958,6 +1958,11 @@ struct Plater::priv
|
|||
wxString get_project_filename(const wxString& extension = wxEmptyString) const;
|
||||
void set_project_filename(const wxString& filename);
|
||||
|
||||
// Caching last value of show_action_buttons parameter for show_action_buttons(), so that a callback which does not know this state will not override it.
|
||||
mutable bool ready_to_slice = { false };
|
||||
// Flag indicating that the G-code export targets a removable device, therefore the show_action_buttons() needs to be called at any case when the background processing finishes.
|
||||
bool writing_to_removable_device = { false };
|
||||
|
||||
private:
|
||||
bool init_object_menu();
|
||||
bool init_common_menu(wxMenu* menu, const bool is_part = false);
|
||||
|
@ -1983,8 +1988,8 @@ private:
|
|||
* we should call tack_snapshot just ones
|
||||
* instead of calls for each action separately
|
||||
* */
|
||||
std::string m_last_fff_printer_profile_name;
|
||||
std::string m_last_sla_printer_profile_name;
|
||||
std::string m_last_fff_printer_profile_name;
|
||||
std::string m_last_sla_printer_profile_name;
|
||||
};
|
||||
|
||||
const std::regex Plater::priv::pattern_bundle(".*[.](amf|amf[.]xml|zip[.]amf|3mf|prusa)", std::regex::icase);
|
||||
|
@ -2156,11 +2161,17 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
// Connect to a 3DConnextion driver (OSX).
|
||||
mouse3d_controller.init();
|
||||
|
||||
this->q->Bind(EVT_REMOVABLE_DRIVE_EJECTED, [this](RemovableDriveEjectEvent &evt) {
|
||||
this->show_action_buttons(this->ready_to_slice);
|
||||
Slic3r::GUI::show_info(this->q, (boost::format(_utf8(L("Unmounting successful. The device %s(%s) can now be safely removed from the computer.")))
|
||||
% evt.data.name % evt.data.path).str());
|
||||
});
|
||||
this->q->Bind(EVT_REMOVABLE_DRIVES_CHANGED, [this](RemovableDrivesChangedEvent &) { this->show_action_buttons(this->ready_to_slice); });
|
||||
// Start the background thread and register this window as a target for update events.
|
||||
wxGetApp().removable_drive_manager()->init(this->q);
|
||||
|
||||
// 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()
|
||||
|
@ -3702,14 +3713,9 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt)
|
|||
sidebar->set_btn_label(ActionButtonType::abReslice, "Slice now");
|
||||
show_action_buttons(true);
|
||||
}
|
||||
else if (wxGetApp().get_mode() == comSimple)
|
||||
show_action_buttons(false);
|
||||
|
||||
if(!canceled && RemovableDriveManager::get_instance().get_is_writing())
|
||||
{
|
||||
RemovableDriveManager::get_instance().set_is_writing(false);
|
||||
show_action_buttons(false);
|
||||
}
|
||||
else if (this->writing_to_removable_device || wxGetApp().get_mode() == comSimple)
|
||||
show_action_buttons(false);
|
||||
this->writing_to_removable_device = false;
|
||||
}
|
||||
|
||||
void Plater::priv::on_layer_editing_toggled(bool enable)
|
||||
|
@ -4269,32 +4275,36 @@ void Plater::priv::update_object_menu()
|
|||
sidebar->obj_list()->append_menu_items_add_volume(&object_menu);
|
||||
}
|
||||
|
||||
void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const
|
||||
void Plater::priv::show_action_buttons(const bool ready_to_slice) const
|
||||
{
|
||||
RemovableDriveManager::get_instance().set_plater_ready_to_slice(is_ready_to_slice);
|
||||
// Cache this value, so that the callbacks from the RemovableDriveManager may repeat that value when calling show_action_buttons().
|
||||
this->ready_to_slice = 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();
|
||||
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")
|
||||
{
|
||||
RemovableDriveManager::RemovableDrivesStatus removable_media_status = wxGetApp().removable_drive_manager()->status();
|
||||
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->show_export_removable(removable_media_status.has_removable_drives) |
|
||||
sidebar->show_disconnect(removable_media_status.has_eject))
|
||||
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_export_removable(export_removable_shown && !is_ready_to_slice) |
|
||||
sidebar->show_disconnect(disconnect_shown && !is_ready_to_slice))
|
||||
RemovableDriveManager::RemovableDrivesStatus removable_media_status;
|
||||
if (! ready_to_slice)
|
||||
removable_media_status = wxGetApp().removable_drive_manager()->status();
|
||||
if (sidebar->show_reslice(ready_to_slice) |
|
||||
sidebar->show_export(!ready_to_slice) |
|
||||
sidebar->show_send(send_gcode_shown && !ready_to_slice) |
|
||||
sidebar->show_export_removable(!ready_to_slice && removable_media_status.has_removable_drives) |
|
||||
sidebar->show_disconnect(!ready_to_slice && removable_media_status.has_eject))
|
||||
sidebar->Layout();
|
||||
}
|
||||
}
|
||||
|
@ -4827,51 +4837,38 @@ void Plater::export_gcode(bool prefer_removable)
|
|||
return;
|
||||
}
|
||||
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());
|
||||
bool removable_drives_connected = GUI::RemovableDriveManager::get_instance().update();
|
||||
if(prefer_removable)
|
||||
{
|
||||
if(removable_drives_connected)
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
AppConfig &appconfig = *wxGetApp().app_config;
|
||||
RemovableDriveManager &removable_drive_manager = *wxGetApp().removable_drive_manager();
|
||||
// Get a last save path, either to removable media or to an internal media.
|
||||
std::string start_dir = appconfig.get_last_output_dir(default_output_file.parent_path().string(), prefer_removable);
|
||||
if (prefer_removable) {
|
||||
// Returns a path to a removable media if it exists, prefering start_dir. Update the internal removable drives database.
|
||||
start_dir = removable_drive_manager.get_removable_drive_path(start_dir);
|
||||
if (start_dir.empty())
|
||||
// Direct user to the last internal media.
|
||||
start_dir = appconfig.get_last_output_dir(default_output_file.parent_path().string(), false);
|
||||
}
|
||||
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()),
|
||||
GUI::file_wildcards((printer_technology() == ptFFF) ? FT_GCODE : FT_PNGZIP, default_output_file.extension().string()),
|
||||
wxFD_SAVE | wxFD_OVERWRITE_PROMPT
|
||||
);
|
||||
|
||||
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(), RemovableDriveManager::get_instance().is_path_on_removable_drive(path.parent_path().string()));
|
||||
output_path = std::move(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()),
|
||||
GUI::file_wildcards((printer_technology() == ptFFF) ? FT_GCODE : FT_PNGZIP, default_output_file.extension().string()),
|
||||
wxFD_SAVE | wxFD_OVERWRITE_PROMPT
|
||||
);
|
||||
if (dlg.ShowModal() == wxID_OK)
|
||||
output_path = into_path(dlg.GetPath());
|
||||
}
|
||||
if (! output_path.empty())
|
||||
{
|
||||
std::string path = output_path.string();
|
||||
p->export_gcode(std::move(output_path), PrintHostJob());
|
||||
|
||||
RemovableDriveManager::get_instance().update(0, false);
|
||||
RemovableDriveManager::get_instance().set_last_save_path(path);
|
||||
RemovableDriveManager::get_instance().verify_last_save_path();
|
||||
|
||||
if(!RemovableDriveManager::get_instance().is_last_drive_removed())
|
||||
{
|
||||
RemovableDriveManager::get_instance().set_is_writing(true);
|
||||
RemovableDriveManager::get_instance().erase_callbacks();
|
||||
RemovableDriveManager::get_instance().add_remove_callback(std::bind(&Plater::drive_ejected_callback, this));
|
||||
}
|
||||
|
||||
if (! output_path.empty()) {
|
||||
p->export_gcode(output_path, PrintHostJob());
|
||||
bool path_on_removable_media = removable_drive_manager.set_and_verify_last_save_path(output_path.string());
|
||||
// Storing a path to AppConfig either as path to removable media or a path to internal media.
|
||||
// is_path_on_removable_drive() is called with the "true" parameter to update its internal database as the user may have shuffled the external drives
|
||||
// while the dialog was open.
|
||||
appconfig.update_last_output_dir(output_path.parent_path().string(), path_on_removable_media);
|
||||
p->writing_to_removable_device = path_on_removable_media;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5193,28 +5190,11 @@ void Plater::send_gcode()
|
|||
}
|
||||
}
|
||||
|
||||
// Called when the Eject button is pressed.
|
||||
void Plater::eject_drive()
|
||||
{
|
||||
RemovableDriveManager::get_instance().update(0, true);
|
||||
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());
|
||||
|
||||
wxGetApp().removable_drive_manager()->eject_drive();
|
||||
}
|
||||
void Plater::drive_ejected_callback()
|
||||
{
|
||||
if (RemovableDriveManager::get_instance().get_did_eject())
|
||||
{
|
||||
RemovableDriveManager::get_instance().set_did_eject(false);
|
||||
show_info(this,
|
||||
(boost::format(_utf8(L("Unmounting successful. The device %s(%s) can now be safely removed from the computer.")))
|
||||
% RemovableDriveManager::get_instance().get_ejected_name()
|
||||
% RemovableDriveManager::get_instance().get_ejected_path()).str());
|
||||
}
|
||||
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); }
|
||||
|
@ -5597,7 +5577,7 @@ void Plater::suppress_background_process(const bool stop_background_process)
|
|||
void Plater::fix_through_netfabb(const int obj_idx, const int vol_idx/* = -1*/) { p->fix_through_netfabb(obj_idx, vol_idx); }
|
||||
|
||||
void Plater::update_object_menu() { p->update_object_menu(); }
|
||||
void Plater::show_action_buttons(const bool is_ready_to_slice) const { p->show_action_buttons(is_ready_to_slice); }
|
||||
void Plater::show_action_buttons(const bool ready_to_slice) const { p->show_action_buttons(ready_to_slice); }
|
||||
|
||||
void Plater::copy_selection_to_clipboard()
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue