forked from viewit/OrcaSlicer-KX
* Add Flashforge AD5X local send dialog, IFS mapping, and LAN discovery * Refine Flashforge AD5X IFS dialog behavior * Refine Flashforge IFS slot selection dialog * Fix Flashforge printer selection and print mapping * Use 3MF for Flashforge local uploads * Generalize Flashforge local API handling * Handle Flashforge local API IFS support more robustly * Use selected plate filament info for Flashforge IFS mapping * Fix Flashforge current-plate mapping and widget sizing * Improve Flashforge IFS contrast and color matching * Fix Flashforge legacy plate export and upload naming Resolve PLATE_CURRENT_IDX before the legacy send-to-printhost path calls send_gcode so single-plate Flashforge 3MF exports target the selected plate instead of leaking the sentinel into export_3mf. Sanitize Flashforge upload names in one shared utility reused by both the dialog and the backend client. This keeps the UI-visible filename and the actual uploaded filename consistent and replaces printer-problematic characters such as '=' without scattering Flashforge-specific logic through the generic Plater flow. * Keep Flashforge upload filename sanitization in the backend only Drop the PrintHostSendDialog API changes and keep filename sanitization inside the Flashforge backend paths that actually talk to the printer. This keeps the generic send dialog flow untouched while still normalizing problematic upload names for both serial and local API uploads. * Only use the Flashforge IFS dialog for local API uploads * Use reported Flashforge IFS support without model fallback * Remove unused Flashforge slot uniqueness tracking * Include <array> for Flashforge discovery message
256 lines
8.9 KiB
C++
256 lines
8.9 KiB
C++
#ifndef slic3r_PrintHostSendDialog_hpp_
|
|
#define slic3r_PrintHostSendDialog_hpp_
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <boost/filesystem/path.hpp>
|
|
|
|
#include <wx/string.h>
|
|
#include <wx/event.h>
|
|
#include <wx/dialog.h>
|
|
|
|
#include "GUI_Utils.hpp"
|
|
#include "MsgDialog.hpp"
|
|
#include "../Utils/PrintHost.hpp"
|
|
#include "../Utils/Flashforge.hpp"
|
|
#include "libslic3r/PrintConfig.hpp"
|
|
#include "libslic3r/ProjectTask.hpp"
|
|
class wxButton;
|
|
class wxTextCtrl;
|
|
class wxComboBox;
|
|
class ComboBox;
|
|
class wxDataViewListCtrl;
|
|
class wxFlexGridSizer;
|
|
class wxStaticText;
|
|
class wxWrapSizer;
|
|
class CheckBox;
|
|
|
|
namespace Slic3r {
|
|
|
|
namespace GUI {
|
|
|
|
class PrintHostSendDialog : public GUI::MsgDialog
|
|
{
|
|
public:
|
|
PrintHostSendDialog(const boost::filesystem::path &path, PrintHostPostUploadActions post_actions, const wxArrayString& groups, const wxArrayString& storage_paths, const wxArrayString& storage_names, bool switch_to_device_tab);
|
|
virtual ~PrintHostSendDialog() {}
|
|
boost::filesystem::path filename() const;
|
|
PrintHostPostUploadAction post_action() const;
|
|
std::string group() const;
|
|
std::string storage() const;
|
|
bool switch_to_device_tab() const {return m_switch_to_device_tab;}
|
|
|
|
virtual void EndModal(int ret) override;
|
|
virtual void init();
|
|
virtual std::map<std::string, std::string> extendedInfo() const { return {}; }
|
|
|
|
protected:
|
|
wxTextCtrl *txt_filename;
|
|
wxComboBox *combo_groups;
|
|
wxComboBox* combo_storage;
|
|
PrintHostPostUploadAction post_upload_action;
|
|
wxString m_valid_suffix;
|
|
wxString m_preselected_storage;
|
|
wxArrayString m_paths;
|
|
bool m_switch_to_device_tab;
|
|
|
|
boost::filesystem::path m_path;
|
|
PrintHostPostUploadActions m_post_actions;
|
|
wxArrayString m_storage_names;
|
|
};
|
|
|
|
|
|
class PrintHostQueueDialog : public DPIDialog
|
|
{
|
|
public:
|
|
class Event : public wxEvent
|
|
{
|
|
public:
|
|
size_t job_id;
|
|
int progress = 0; // in percent
|
|
wxString tag;
|
|
wxString status;
|
|
|
|
Event(wxEventType eventType, int winid, size_t job_id);
|
|
Event(wxEventType eventType, int winid, size_t job_id, int progress);
|
|
Event(wxEventType eventType, int winid, size_t job_id, wxString error);
|
|
Event(wxEventType eventType, int winid, size_t job_id, wxString tag, wxString status);
|
|
|
|
virtual wxEvent *Clone() const;
|
|
};
|
|
|
|
|
|
PrintHostQueueDialog(wxWindow *parent);
|
|
|
|
void append_job(const PrintHostJob &job);
|
|
void get_active_jobs(std::vector<std::pair<std::string, std::string>>& ret);
|
|
|
|
virtual bool Show(bool show = true) override
|
|
{
|
|
if(!show)
|
|
save_user_data(UDT_SIZE | UDT_POSITION | UDT_COLS);
|
|
return DPIDialog::Show(show);
|
|
}
|
|
protected:
|
|
void on_dpi_changed(const wxRect &suggested_rect) override;
|
|
void on_sys_color_changed() override;
|
|
|
|
private:
|
|
enum Column {
|
|
COL_ID,
|
|
COL_PROGRESS,
|
|
COL_STATUS,
|
|
COL_HOST,
|
|
COL_SIZE,
|
|
COL_FILENAME,
|
|
COL_ERRORMSG
|
|
};
|
|
|
|
enum JobState {
|
|
ST_NEW,
|
|
ST_PROGRESS,
|
|
ST_ERROR,
|
|
ST_CANCELLING,
|
|
ST_CANCELLED,
|
|
ST_COMPLETED,
|
|
};
|
|
|
|
enum { HEIGHT = 60, WIDTH = 30, SPACING = 5 };
|
|
|
|
enum UserDataType{
|
|
UDT_SIZE = 1,
|
|
UDT_POSITION = 2,
|
|
UDT_COLS = 4
|
|
};
|
|
|
|
wxButton *btn_cancel;
|
|
wxButton *btn_error;
|
|
wxDataViewListCtrl *job_list;
|
|
// Note: EventGuard prevents delivery of progress evts to a freed PrintHostQueueDialog
|
|
EventGuard on_progress_evt;
|
|
EventGuard on_error_evt;
|
|
EventGuard on_cancel_evt;
|
|
EventGuard on_info_evt;
|
|
|
|
JobState get_state(int idx);
|
|
void set_state(int idx, JobState);
|
|
void on_list_select();
|
|
void on_progress(Event&);
|
|
void on_error(Event&);
|
|
void on_cancel(Event&);
|
|
void on_info(Event&);
|
|
// This vector keep adress and filename of uploads. It is used when checking for running uploads during exit.
|
|
std::vector<std::pair<std::string, std::string>> upload_names;
|
|
void save_user_data(int);
|
|
bool load_user_data(int, std::vector<int>&);
|
|
};
|
|
|
|
class ElegooPrintHostSendDialog : public PrintHostSendDialog
|
|
{
|
|
public:
|
|
ElegooPrintHostSendDialog(const boost::filesystem::path& path,
|
|
PrintHostPostUploadActions post_actions,
|
|
const wxArrayString& groups,
|
|
const wxArrayString& storage_paths,
|
|
const wxArrayString& storage_names,
|
|
bool switch_to_device_tab);
|
|
|
|
virtual void EndModal(int ret) override;
|
|
int timeLapse() const { return m_timeLapse; }
|
|
int heatedBedLeveling() const { return m_heatedBedLeveling; }
|
|
BedType bedType() const { return m_BedType; }
|
|
|
|
virtual void init() override;
|
|
virtual std::map<std::string, std::string> extendedInfo() const
|
|
{
|
|
return {{"bedType", std::to_string(static_cast<int>(m_BedType))},
|
|
{"timeLapse", std::to_string(m_timeLapse)},
|
|
{"heatedBedLeveling", std::to_string(m_heatedBedLeveling)}};
|
|
}
|
|
|
|
private:
|
|
BedType appBedType() const;
|
|
void refresh();
|
|
|
|
const char* CONFIG_KEY_UPLOADANDPRINT = "elegoolink_upload_and_print";
|
|
const char* CONFIG_KEY_TIMELAPSE = "elegoolink_timelapse";
|
|
const char* CONFIG_KEY_HEATEDBEDLEVELING = "elegoolink_heated_bed_leveling";
|
|
const char* CONFIG_KEY_BEDTYPE = "elegoolink_bed_type";
|
|
|
|
private:
|
|
wxStaticText* warning_text{nullptr};
|
|
wxBoxSizer* uploadandprint_sizer{nullptr};
|
|
|
|
int m_timeLapse;
|
|
int m_heatedBedLeveling;
|
|
BedType m_BedType;
|
|
};
|
|
|
|
class FlashforgePrintHostSendDialog : public PrintHostSendDialog
|
|
{
|
|
public:
|
|
FlashforgePrintHostSendDialog(const boost::filesystem::path& path,
|
|
PrintHostPostUploadActions post_actions,
|
|
const wxArrayString& groups,
|
|
const wxArrayString& storage_paths,
|
|
const wxArrayString& storage_names,
|
|
bool switch_to_device_tab,
|
|
const Slic3r::Flashforge* host,
|
|
bool supports_material_station,
|
|
std::vector<Slic3r::FlashforgeMaterialSlot> slots,
|
|
const std::vector<FilamentInfo>& project_filaments);
|
|
|
|
virtual void init() override;
|
|
virtual void EndModal(int ret) override;
|
|
virtual std::map<std::string, std::string> extendedInfo() const override;
|
|
|
|
private:
|
|
struct MappingRow {
|
|
int tool_id {-1};
|
|
wxWindow* card {nullptr};
|
|
};
|
|
|
|
void load_slots();
|
|
bool ensure_slots_loaded(bool force_reload = false);
|
|
void rebuild_mapping_rows();
|
|
void auto_assign_mappings();
|
|
void refresh_mapping_card(MappingRow& row);
|
|
void sync_mapping_section_visibility();
|
|
const Slic3r::FlashforgeMaterialSlot* find_slot_by_id(const std::string& slot_id_text) const;
|
|
const FilamentInfo* find_filament_by_tool_id(int tool_id) const;
|
|
bool slot_matches_filament(const Slic3r::FlashforgeMaterialSlot& slot, const FilamentInfo& filament) const;
|
|
bool validate_before_close();
|
|
std::string normalize_material(const std::string& material) const;
|
|
wxColour to_wx_colour(const std::string& color) const;
|
|
|
|
private:
|
|
const Slic3r::Flashforge* m_host {nullptr};
|
|
std::vector<FilamentInfo> m_project_filaments;
|
|
std::vector<Slic3r::FlashforgeMaterialSlot> m_slots;
|
|
std::vector<MappingRow> m_mapping_rows;
|
|
wxBoxSizer* m_flashforge_options_sizer {nullptr};
|
|
wxBoxSizer* m_mapping_section_sizer {nullptr};
|
|
wxWrapSizer* m_mapping_wrap_sizer {nullptr};
|
|
wxStaticText* m_status_text {nullptr};
|
|
::CheckBox* m_checkbox_leveling {nullptr};
|
|
::CheckBox* m_checkbox_timelapse {nullptr};
|
|
::CheckBox* m_checkbox_ifs {nullptr};
|
|
bool m_leveling_before_print {true};
|
|
bool m_time_lapse_video {false};
|
|
bool m_use_material_station {false};
|
|
bool m_supports_material_station {false};
|
|
bool m_slots_loaded {false};
|
|
|
|
const char* CONFIG_KEY_LEVELING = "flashforge_leveling_before_print";
|
|
const char* CONFIG_KEY_TIMELAPSE = "flashforge_timelapse_video";
|
|
const char* CONFIG_KEY_IFS = "flashforge_use_material_station";
|
|
};
|
|
|
|
wxDECLARE_EVENT(EVT_PRINTHOST_PROGRESS, PrintHostQueueDialog::Event);
|
|
wxDECLARE_EVENT(EVT_PRINTHOST_ERROR, PrintHostQueueDialog::Event);
|
|
wxDECLARE_EVENT(EVT_PRINTHOST_CANCEL, PrintHostQueueDialog::Event);
|
|
wxDECLARE_EVENT(EVT_PRINTHOST_INFO, PrintHostQueueDialog::Event);
|
|
}}
|
|
|
|
#endif
|