OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::GUI::GUI_App Class Reference

#include </home/runner/work/OrcaSlicer/OrcaSlicer/src/slic3r/GUI/GUI_App.hpp>

Inheritance diagram for Slic3r::GUI::GUI_App:
Collaboration diagram for Slic3r::GUI::GUI_App:

Public Types

enum class  EAppMode : unsigned char { Editor , GCodeViewer }

Public Member Functions

void on_start_subscribe_again (std::string dev_id)
void reset_unsigned_plugin_warning ()
std::string get_local_models_path ()
bool OnInit () override
int OnExit () override
void CleanUp () override
bool initialized () const
bool is_enable_multi_machine ()
 GUI_App ()
 ~GUI_App () override
void show_message_box (std::string msg)
EAppMode get_app_mode () const
Slic3r::DeviceManager * getDeviceManager ()
bool is_blocking_printing (MachineObject *obj_=nullptr)
bool is_blocking_printing (MachineObject *obj_, const std::string &source_model)
Slic3r::TaskManager * getTaskManager ()
HMSQuery * get_hms_query ()
NetworkAgent * getAgent ()
const boost::optional< Semver > & last_config_version () const
void switch_printer_agent ()
void switch_printer_agent_if_pending ()
std::string resolve_printer_agent_id (const std::string &stored_id) const
std::string canonical_printer_agent_id (const std::string &picked_id)
FilamentColorCodeQuery * get_filament_color_code_query ()
bool is_editor () const
bool is_gcode_viewer () const
bool is_recreating_gui () const
int input_idle_ms () const
int FilterEvent (wxEvent &event) override
bool starts_on_prepare () const
std::string logo_name () const
bool is_closing () const
void set_closing (bool closing)
void start_exit_watchdog ()
bool show_gcode_window () const
void toggle_show_gcode_window ()
bool show_3d_navigator () const
void toggle_show_3d_navigator () const
bool show_plate_gridlines () const
void toggle_show_plate_gridlines () const
bool focus_mode () const
void toggle_focus_mode () const
bool show_canvas_zoom_button () const
void toggle_canvas_zoom_button () const
bool show_outline () const
void toggle_show_outline () const
bool show_center_of_mass () const
void toggle_show_center_of_mass () const
wxString get_inf_dialog_contect ()
std::vector< std::string > split_str (std::string src, std::string separator)
void post_init ()
void shutdown ()
wxGLContext * init_glcontext (wxGLCanvas &canvas)
bool init_opengl ()
void init_download_path ()
void open_orca_cloud (const std::string &next=std::string())
const wxColour get_label_default_clr_system ()
const wxColour get_label_default_clr_modified ()
void init_label_colours ()
void update_label_colours_from_appconfig ()
void update_publish_status ()
bool has_model_mall ()
void update_label_colours ()
void UpdateDarkUI (wxWindow *window, bool highlited=false, bool just_font=false)
void UpdateDarkUIWin (wxWindow *win)
void Update_dark_mode_flag ()
void UpdateDlgDarkUI (wxDialog *dlg)
void UpdateFrameDarkUI (wxFrame *dlg)
void UpdateDVCDarkUI (wxDataViewCtrl *dvc, bool highlited=false)
void UpdateAllStaticTextDarkUI (wxWindow *parent)
void init_fonts ()
void update_fonts (const MainFrame *main_frame=nullptr)
void set_label_clr_modified (const wxColour &clr)
void set_label_clr_sys (const wxColour &clr)
bool get_side_menu_popup_status ()
void set_side_menu_popup_status (bool status)
std::string link_to_network_check ()
std::string link_to_lan_only_wiki ()
const wxColour & get_label_clr_modified ()
const wxColour & get_label_clr_sys ()
const wxColour & get_label_clr_default ()
const wxColour & get_window_default_clr ()
const wxColour & get_label_highlight_clr ()
const wxColour & get_highlight_default_clr ()
const wxColour & get_color_hovered_btn_label ()
const wxColour & get_color_selected_btn_bg ()
void force_colors_update ()
void force_menu_update ()
const wxFont & small_font ()
const wxFont & bold_font ()
const wxFont & normal_font ()
const wxFont & code_font ()
const wxFont & link_font ()
int em_unit () const
bool tabs_as_menu () const
wxSize get_min_size () const
float toolbar_icon_scale (const bool is_limited=false) const
void set_auto_toolbar_icon_scale (float scale) const
void check_printer_presets ()
void recreate_GUI (const wxString &message)
void keyboard_shortcuts (ShortcutContext page, wxWindow *parent=nullptr)
void troubleshoot ()
void load_project (wxWindow *parent, wxString &input_file) const
void import_model (wxWindow *parent, wxArrayString &input_files) const
void import_zip (wxWindow *parent, wxString &input_file) const
void load_gcode (wxWindow *parent, wxString &input_file) const
wxString transition_tridid (int trid_id) const
void ShowUserGuide ()
void ShowDownNetPluginDlg ()
void ShowUserLogin (bool show=true, const std::string &provider=ORCA_CLOUD_PROVIDER)
void ShowOnlyFilament ()
void request_login (bool show_user_info=false, const std::string &provider=ORCA_CLOUD_PROVIDER)
bool check_login (const std::string &provider=ORCA_CLOUD_PROVIDER)
void get_login_info (const std::string &provider=ORCA_CLOUD_PROVIDER)
bool is_user_login (const std::string &provider=ORCA_CLOUD_PROVIDER)
std::string get_printer_cloud_provider () const
void request_user_login (int online_login=0, const std::string &provider=ORCA_CLOUD_PROVIDER)
void request_user_handle (int online_login=0, const std::string &provider=ORCA_CLOUD_PROVIDER)
void request_user_logout (const std::string &provider=ORCA_CLOUD_PROVIDER, bool user_initiated=false)
void post_logout_to_webview (const std::string &provider)
int request_user_unbind (std::string dev_id, const std::string &provider=ORCA_CLOUD_PROVIDER)
std::string handle_web_request (std::string cmd)
void handle_script_message (std::string msg, const std::string &provider=ORCA_CLOUD_PROVIDER)
void request_model_download (wxString url)
void download_project (std::string project_id)
void request_project_download (std::string project_id)
void request_open_project (std::string project_id)
void request_remove_project (std::string project_id)
void handle_http_error (unsigned int status, std::string body, const std::string &provider="")
void on_http_error (wxCommandEvent &evt)
void on_update_machine_list (wxCommandEvent &evt)
void on_user_login (wxCommandEvent &evt)
void on_user_login_handle (wxCommandEvent &evt)
wxString cloud_webview_handoff (const std::string &next=std::string())
void request_cloud_web_session (const std::string &state)
void mint_cloud_web_session (const std::string &state, uint64_t gen)
void on_cloud_web_session_minted (const std::string &state, uint64_t gen, const std::string &token_hash)
void enable_user_preset_folder (bool enable)
bool is_studio_active ()
void reset_to_active ()
void check_update (bool show_tips, int by_user)
void check_new_version (bool show_tips=false, int by_user=0)
void check_new_version_sf (bool show_tips=false, int by_user=0)
void check_legacy_user_filament_presets (bool by_user)
bool process_network_msg (std::string dev_id, std::string msg)
void request_new_version (int by_user)
void enter_force_upgrade ()
void set_skip_version (bool skip=true)
void no_new_version ()
std::string format_IP (const std::string &ip)
void show_dialog (wxString msg)
void push_notification (const MachineObject *obj, wxString msg, wxString title=wxEmptyString, UserNotificationStyle style=UserNotificationStyle::UNS_NORMAL)
bool reload_settings ()
void remove_user_presets ()
bool maybe_migrate_user_presets_on_login ()
bool check_preset_parent_available (const std::pair< std::string, std::map< std::string, std::string > > &preset_data)
void add_pending_vendor_preset (const std::pair< std::string, std::map< std::string, std::string > > &preset_data)
void load_pending_vendors ()
void sync_preset (Preset *preset, bool force=false)
void start_sync_user_preset (bool with_progress_dlg=false)
void stop_sync_user_preset ()
void restart_sync_user_preset ()
void force_push_conflicting_preset (const std::string &setting_id)
void on_stealth_mode_enter ()
void check_bundle_updates ()
int sync_bundle (std::string bundle_id, std::string version)
bool unsubscribe_bundle (const std::string &id)
void update_single_bundle (wxCommandEvent &evt)
void start_http_server (const std::string &provider=ORCA_CLOUD_PROVIDER)
void start_http_server (int port, const std::string &provider=ORCA_CLOUD_PROVIDER)
void stop_http_server ()
void on_show_check_privacy_dlg (int online_login=0, const std::string &provider=ORCA_CLOUD_PROVIDER)
void show_check_privacy_dlg (wxCommandEvent &evt)
void on_check_privacy_update (wxCommandEvent &evt)
bool check_privacy_update ()
void check_privacy_version (int online_login=0, const std::string &provider=ORCA_CLOUD_PROVIDER)
void check_track_enable ()
void persist_window_geometry (wxTopLevelWindow *window, bool default_maximized=false)
void update_ui_from_settings ()
bool load_language (wxString language, bool initial)
Tab * get_tab (Preset::Type type)
Tab * get_plate_tab ()
Tab * get_model_tab (bool part=false)
Tab * get_layer_tab ()
ConfigOptionMode get_saved_mode ()
ConfigOptionMode get_mode ()
std::string get_saved_mode_str ()
std::string get_mode_str ()
void save_mode (const int mode)
void set_mode (ConfigOptionMode mode)
void enable_developer_mode ()
void update_mode ()
void update_internal_development ()
void show_ip_address_enter_dialog (wxString title=wxEmptyString)
void show_ip_address_enter_dialog_handler (wxCommandEvent &evt)
bool show_modal_ip_address_enter_dialog (bool input_sn, wxString title=wxEmptyString)
bool has_unsaved_preset_changes () const
bool has_current_preset_changes () const
void update_saved_preset_from_current_preset ()
std::vector< std::pair< unsigned int, std::string > > get_selected_presets () const
bool check_and_save_current_preset_changes (const wxString &caption, const wxString &header, bool remember_choice=true, bool use_dont_save_insted_of_discard=false)
void apply_keeped_preset_modifications ()
bool check_and_keep_current_preset_changes (const wxString &caption, const wxString &header, int action_buttons, bool *postponed_apply_of_keeped_changes=nullptr)
bool can_load_project ()
bool check_print_host_queue ()
bool checked_tab (Tab *tab)
void load_current_presets (bool active_preset_combox=false, bool check_printer_presets=true)
std::map< std::string, std::string > & get_delete_cache_presets ()
std::map< std::string, std::string > get_delete_cache_presets_lock ()
void process_delete_presets ()
void delete_preset_from_cloud (std::string setting_id, std::string preset_file_path)
void preset_deleted_from_cloud (std::string setting_id)
void scan_orphaned_info_files ()
wxString filter_string (wxString str)
wxString current_language_code () const
wxString current_language_code_safe () const
bool is_localized () const
void open_preferences ()
void open_preferences (PreferencesTab tab, const std::string &highlight_option=std::string())
void open_presetbundledialog (size_t open_on_tab=0, const std::string &highlight_option=std::string())
void open_plugins_dialog (size_t open_on_tab=0, const std::string &highlight_option=std::string())
void refresh_plugins ()
void install_local_plugin ()
void open_terminal_dialog ()
void open_speed_dial ()
ActionRegistry & action_registry ()
void open_exportpresetbundledialog (size_t open_on_tab=0, const std::string &highlight_option=std::string())
virtual bool OnExceptionInMainLoop () override
bool open_browser_with_warning_dialog (const wxString &url, int flags=0)
Sidebar & sidebar ()
GizmoObjectManipulation * obj_manipul ()
ObjectSettings * obj_settings ()
ObjectList * obj_list ()
ObjectLayers * obj_layers ()
Plater * plater ()
const Plater * plater () const
ParamsPanel * params_panel ()
ParamsDialog * params_dialog ()
Model & model ()
NotificationManager * notification_manager ()
Downloader * downloader ()
void set_download_model_url (std::string url)
void set_download_model_name (std::string name)
std::string get_download_model_url ()
std::string get_download_model_name ()
void load_url (wxString url)
void open_mall_page_dialog ()
void open_publish_page_dialog ()
void remove_mall_system_dialog ()
void run_script (wxString js)
bool is_adding_script_handler ()
void set_adding_script_handler (bool status)
char from_hex (char ch)
std::string url_encode (std::string value)
std::string url_decode (std::string value)
void popup_ping_bind_dialog ()
void remove_ping_bind_dialog ()
PresetUpdater * get_preset_updater ()
Notebook * tab_panel () const
int extruders_cnt () const
int extruders_edited_cnt () const
int filaments_cnt () const
PrintSequence global_print_sequence () const
RemovableDriveManager * removable_drive_manager ()
OtherInstanceMessageHandler * other_instance_message_handler ()
wxSingleInstanceChecker * single_instance_checker ()
void init_single_instance_checker (const std::string &name, const std::string &path)
void set_instance_hash (const size_t hash)
std::string get_instance_hash_string ()
size_t get_instance_hash_int ()
ImGuiWrapper * imgui ()
ShortcutRegistry & shortcuts ()
void on_shortcuts_changed ()
PrintHostJobQueue & printhost_job_queue ()
void open_web_page_localized (const std::string &http_address)
bool may_switch_to_SLA_preset (const wxString &caption)
bool run_wizard (ConfigWizard::RunReason reason, ConfigWizard::StartPage start_page=ConfigWizard::SP_WELCOME)
void show_desktop_integration_dialog ()
OpenGLManager & get_opengl_manager ()
GLShaderProgram * get_shader (const std::string &shader_name)
GLShaderProgram * get_current_shader ()
bool is_gl_version_greater_or_equal_to (unsigned int major, unsigned int minor) const
bool is_glsl_version_greater_or_equal_to (unsigned int major, unsigned int minor) const
int GetSingleChoiceIndex (const wxString &message, const wxString &caption, const wxArrayString &choices, int initialSelection)
void associate_files (std::wstring extend)
void disassociate_files (std::wstring extend)
bool check_url_association (std::wstring url_prefix, std::wstring &reg_bin)
void associate_url (std::wstring url_prefix)
void disassociate_url (std::wstring url_prefix)
void start_download (std::string url)
std::string get_plugin_url (std::string name, std::string country_code)
int download_plugin (std::string name, std::string package_name, InstallProgressFn pro_fn=nullptr, WasCancelledFn cancel_fn=nullptr)
int install_plugin (std::string name, std::string package_name, InstallProgressFn pro_fn=nullptr, WasCancelledFn cancel_fn=nullptr)
std::string get_http_url (std::string country_code, std::string path={})
std::string get_model_http_url (std::string country_code)
bool use_legacy_network_plugin () const
bool is_compatibility_version ()
bool check_networking_version ()
void cancel_networking_install ()
void restart_networking ()
void check_config_updates_from_updater ()
void show_network_plugin_download_dialog (bool is_update=false)
void migrate_network_plugin_config ()
bool hot_reload_network_plugin ()
bool install_network_plugin_from_ota (bool &had_cache)
std::string get_latest_network_version () const
bool has_network_update_available () const
std::string get_bbl_client_version ()

Static Public Member Functions

static std::string get_gl_info (bool for_github)
static unsigned get_colour_approx_luma (const wxColour &colour)
static bool dark_mode ()
static std::string format_display_version ()
static bool catch_error (std::function< void()> cb, const std::string &err)
static std::string extract_setting_id_from_info (const std::string &info_file_path)

Public Attributes

std::map< std::string, bool > test_url_state
bool m_studio_active = true
std::chrono::system_clock::time_point last_active_point
PresetBundleDialog * m_preset_bundle_dlg {nullptr}
PluginsDialog * m_plugins_dlg {nullptr}
SpeedDialWebDialog * m_speed_dial_dialog {nullptr}
TerminalDialog * m_terminal_dlg {nullptr}
ActionRegistry m_action_registry
std::string m_mall_model_download_url
std::string m_mall_model_download_name
ModelMallDialog * m_mall_publish_dialog { nullptr }
PingCodeBindDialog * m_ping_code_binding_dialog { nullptr }
NetworkErrorDialog * m_server_error_dialog { nullptr }
GUI_InitParams * init_params { nullptr }
AppConfig * app_config { nullptr }
PresetBundle * preset_bundle { nullptr }
PresetUpdater * preset_updater { nullptr }
MainFrame * mainframe { nullptr }
Plater * plater_ { nullptr }
std::vector< Tab * > tabs_list
std::vector< Tab * > model_tabs_list
Tab * plate_tab

Private Member Functions

int updating_bambu_networking ()
bool on_init_inner ()
void copy_network_if_available ()
bool on_init_network (bool try_backup=false)
void init_networking_callbacks ()
void init_app_config ()
void init_plugin_gui_wiring ()
void remove_old_networking_plugins ()
void drain_pending_events (int timeout_ms)
bool wait_for_network_idle (int timeout_ms)
bool check_older_app_config (Semver current_version, bool backup)
void copy_older_config ()
void window_pos_save (wxTopLevelWindow *window, const std::string &name)
bool window_pos_restore (wxTopLevelWindow *window, const std::string &name, bool default_maximized=false)
void window_pos_sanitize (wxTopLevelWindow *window)
void window_pos_center (wxTopLevelWindow *window)
void refresh_printer_agent_dropdown ()
void set_live_printer_agent (std::shared_ptr< IPrinterAgent > agent)
bool config_wizard_startup ()
void check_updates (const bool verbose)
void select_machine (const std::string &agent_id)

Private Attributes

bool m_initialized { false }
bool m_post_initialized { false }
bool m_app_conf_exists { false }
EAppMode m_app_mode { EAppMode::Editor }
bool m_is_recreating_gui { false }
std::chrono::steady_clock::time_point m_last_input { std::chrono::steady_clock::now() }
wxColour m_color_label_modified
wxColour m_color_label_sys
wxColour m_color_label_default
wxColour m_color_window_default
wxColour m_color_highlight_label_default
wxColour m_color_hovered_btn_label
wxColour m_color_default_btn_label
wxColour m_color_highlight_default
wxColour m_color_selected_btn_bg
bool m_force_colors_update { false }
wxFont m_small_font
wxFont m_bold_font
wxFont m_normal_font
wxFont m_code_font
wxFont m_link_font
int m_em_unit
std::unique_ptr< wxLocale > m_wxLocale
const wxLanguageInfo * m_language_info_system = nullptr
const wxLanguageInfo * m_language_info_best = nullptr
wxString m_active_language_code
OpenGLManager m_opengl_mgr
std::unique_ptr< RemovableDriveManager > m_removable_drive_manager
std::unique_ptr< ImGuiWrapper > m_imgui
std::unique_ptr< ShortcutRegistry > m_shortcuts
std::unique_ptr< PrintHostJobQueue > m_printhost_job_queue
std::unique_ptr< OtherInstanceMessageHandler > m_other_instance_message_handler
std::unique_ptr< wxSingleInstanceChecker > m_single_instance_checker
std::string m_instance_hash_string
size_t m_instance_hash_int
std::unique_ptr< Downloader > m_downloader
std::atomic< bool > m_is_closing {false}
Slic3r::DeviceManager * m_device_manager { nullptr }
Slic3r::UserManager * m_user_manager { nullptr }
Slic3r::TaskManager * m_task_manager { nullptr }
NetworkAgent * m_agent { nullptr }
std::map< std::string, std::string > need_delete_presets
std::vector< bool > m_create_preset_blocked { false, false, false, false, false, false }
std::vector< std::string > m_pending_conflict_setting_ids
bool m_networking_compatible { false }
bool m_networking_need_update { false }
bool m_networking_cancel_update { false }
std::shared_ptr< UpgradeNetworkJob > m_upgrade_network_job
std::map< std::string, std::map< std::string, std::set< std::string > > > need_add_vendors
std::map< std::string, std::string > need_add_filaments
ZUserLogin * login_dlg { nullptr }
VersionInfo version_info
VersionInfo privacy_version_info
HMSQuery * hms_query { nullptr }
FilamentColorCodeQuery * m_filament_color_code_query { nullptr }
boost::thread m_sync_update_thread
std::shared_ptr< int > m_user_sync_token
std::atomic< bool > m_restart_sync_pending {false}
std::atomic< bool > m_sync_user_preset_dlg_active {false}
std::atomic< bool > m_sync_user_presets_now {false}
bool m_user_preset_pull_pending {false}
bool m_legacy_filament_check_due {false}
bool m_legacy_filament_check_running {false}
std::atomic< bool > m_migration_retry_pending {false}
bool m_is_dark_mode { false }
bool m_adding_script_handler { false }
bool m_side_popup_status {false}
bool m_show_http_error_msgdlg {false}
std::chrono::steady_clock::time_point m_last_401_error_time
std::string m_cloud_handoff_state
std::string m_cloud_open_path
uint64_t m_cloud_handoff_gen { 0 }
bool m_show_error_msgdlg {false}
wxString m_info_dialog_content
HttpServer m_http_server
bool m_show_gcode_window {true}
boost::thread m_check_network_thread
bool m_init_app_config_from_older { false }
bool m_datadir_redefined { false }
std::string m_older_data_dir_path
bool m_unsigned_plugin_warning_shown { false }
boost::optional< Semver > m_last_config_version
bool m_config_corrupted { false }
std::string m_open_method

Static Private Attributes

static std::string version_display = ""

Detailed Description

Member Enumeration Documentation

◆ EAppMode

enum class Slic3r::GUI::GUI_App::EAppMode : unsigned char
strong
Enumerator
Editor 
GCodeViewer 
260 {
261 Editor,
263 };
@ GCodeViewer
Definition Process.cpp:38

Constructor & Destructor Documentation

◆ GUI_App()

Slic3r::GUI::GUI_App::GUI_App ( )
explicit
1253 : wxApp()
1254 //, m_app_mode(mode)
1256 , m_em_unit(10)
1257 , m_imgui(new ImGuiWrapper())
1258 , m_removable_drive_manager(std::make_unique<RemovableDriveManager>())
1259 , m_downloader(std::make_unique<Downloader>())
1260 , m_other_instance_message_handler(std::make_unique<OtherInstanceMessageHandler>())
1261{
1262 //app config initializes early becasuse it is used in instance checking in OrcaSlicer.cpp
1263 this->init_app_config();
1264 m_shortcuts = std::make_unique<ShortcutRegistry>();
1265 m_shortcuts->load(*app_config);
1266 this->init_download_path();
1267 // Note: the WebView2 runtime check (init_webview_runtime) used to run here, but
1268 // the constructor executes before wxWidgets is fully initialized and before the
1269 // event loop starts, so its modal prompt/installer could silently fail to appear.
1270 // It now runs in post_init(), before the first WebView (the setup wizard) is created.
1271
1273}
std::unique_ptr< ImGuiWrapper > m_imgui
Definition GUI_App.hpp:312
int m_em_unit
Definition GUI_App.hpp:299
std::unique_ptr< ShortcutRegistry > m_shortcuts
Definition GUI_App.hpp:313
void reset_to_active()
Definition GUI_App.cpp:6187
std::unique_ptr< RemovableDriveManager > m_removable_drive_manager
Definition GUI_App.hpp:310
std::unique_ptr< OtherInstanceMessageHandler > m_other_instance_message_handler
Definition GUI_App.hpp:315
@ Editor
Definition GUI_App.hpp:261
void init_app_config()
Definition GUI_App.cpp:2719
AppConfig * app_config
Definition GUI_App.hpp:787
std::unique_ptr< Downloader > m_downloader
Definition GUI_App.hpp:320
void init_download_path()
Definition GUI_App.cpp:2659
EAppMode m_app_mode
Definition GUI_App.hpp:269

References GUI_App(), app_config, init_app_config(), init_download_path(), m_app_mode, m_downloader, m_em_unit, m_imgui, m_other_instance_message_handler, m_removable_drive_manager, m_shortcuts, Slic3r::make_unique(), and reset_to_active().

Referenced by GUI_App(), and init_plugin_gui_wiring().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ~GUI_App()

Slic3r::GUI::GUI_App::~GUI_App ( )
override
2560{
2561 BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": enter");
2562
2563 if (m_agent)
2564 m_agent->set_printer_agent(nullptr);
2566
2569
2570 if (app_config != nullptr) {
2571 BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": destroy app_config");
2572 delete app_config;
2573 }
2574
2575 if (preset_bundle != nullptr) {
2576 BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": destroy preset_bundle");
2577 delete preset_bundle;
2578 }
2579
2580 if (preset_updater != nullptr) {
2581 BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": destroy preset updater");
2582 delete preset_updater;
2583 }
2584
2587
2588
2589 BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": exit");
2591}
static void shutdown()
Definition BBLNetworkPlugin.cpp:65
PresetBundle * preset_bundle
Definition GUI_App.hpp:788
PresetUpdater * preset_updater
Definition GUI_App.hpp:789
NetworkAgent * m_agent
Definition GUI_App.hpp:327
static void clear_printer_agent_cache()
Definition NetworkAgentFactory.cpp:167
static PluginManager & instance()
Definition PluginManager.cpp:74
void shutdown()
Definition PluginManager.cpp:150
static PythonInterpreter & instance()
Definition PythonInterpreter.cpp:434
void shutdown()
Definition PythonInterpreter.cpp:691
void shutdown_console_logging()
Definition utils.cpp:413
static void release()
Definition PrinterFileSystem.cpp:1903

References ~GUI_App(), app_config, Slic3r::NetworkAgentFactory::clear_printer_agent_cache(), Slic3r::PluginManager::instance(), Slic3r::PythonInterpreter::instance(), m_agent, preset_bundle, preset_updater, StaticBambuLib::release(), Slic3r::BBLNetworkPlugin::shutdown(), Slic3r::PluginManager::shutdown(), Slic3r::PythonInterpreter::shutdown(), and Slic3r::shutdown_console_logging().

Referenced by ~GUI_App().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Function Documentation

◆ action_registry()

ActionRegistry & Slic3r::GUI::GUI_App::action_registry ( )
inline
727{ return m_action_registry; }
ActionRegistry m_action_registry
Definition GUI_App.hpp:648

References m_action_registry.

◆ add_pending_vendor_preset()

void Slic3r::GUI::GUI_App::add_pending_vendor_preset ( const std::pair< std::string, std::map< std::string, std::string > > & preset_data)
7385{
7387 if (preset_data.second.at(BBL_JSON_KEY_TYPE) == PRESET_IOT_PRINT_TYPE)
7389 else if (preset_data.second.at(BBL_JSON_KEY_TYPE) == PRESET_IOT_PRINTER_TYPE)
7391 else if (preset_data.second.at(BBL_JSON_KEY_TYPE) == PRESET_IOT_FILAMENT_TYPE)
7393 std::string inherits_name = preset_data.second.at(BBL_JSON_KEY_INHERITS);
7394
7395 // Add the corresponding vendor
7396 std::string vendor_name = PresetBundle::find_preset_vendor(inherits_name, type);
7397 if (vendor_name.empty()) {
7398 // No vendor ships this preset's parent. An unnamed entry here becomes an
7399 // unnamed bundle at install time, which nothing can install.
7400 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": no vendor carries " << inherits_name << ", skipping";
7401 return;
7402 }
7403 if (need_add_vendors.find(vendor_name) == need_add_vendors.end())
7404 need_add_vendors[vendor_name] = std::map<std::string, std::set<std::string>>();
7405
7406 // Add printers/filament if applicable
7407 if (type == Preset::Type::TYPE_PRINTER) {
7408 // Extract float from preset name if present
7409 std::string model_name = inherits_name;
7410 std::regex float_regex(R"((\b\d+\.\d+))");
7411 std::smatch match;
7412 if (std::regex_search(model_name, match, float_regex) && match.size() > 1) {
7413 // Get variant i.e., nozzle diameter
7414 std::string nozzle_diameter = match[1].str();
7415 // Get model name
7416 model_name.erase(model_name.find(nozzle_diameter));
7417 model_name.erase(model_name.rfind(' '));
7418 if(need_add_vendors[vendor_name].find(model_name) == need_add_vendors[vendor_name].end())
7419 need_add_vendors[vendor_name][model_name] = std::set<std::string>();
7420
7421 need_add_vendors[vendor_name][model_name].insert(nozzle_diameter);
7422 }
7423 }
7424 else if (type == Preset::Type::TYPE_FILAMENT) {
7425 need_add_filaments[inherits_name] = "true";
7426 }
7427}
#define PRESET_IOT_FILAMENT_TYPE
Definition Preset.hpp:50
#define BBL_JSON_KEY_TYPE
Definition Preset.hpp:66
#define PRESET_IOT_PRINT_TYPE
Definition Preset.hpp:51
#define PRESET_IOT_PRINTER_TYPE
Definition Preset.hpp:49
#define BBL_JSON_KEY_INHERITS
Definition Preset.hpp:75
std::map< std::string, std::string > need_add_filaments
Definition GUI_App.hpp:342
std::map< std::string, std::map< std::string, std::set< std::string > > > need_add_vendors
Definition GUI_App.hpp:341
static std::string find_preset_vendor(const std::string &preset_name, Preset::Type type)
Definition PresetBundle.cpp:403
Type
Definition Preset.hpp:244
@ TYPE_PRINTER
Definition Preset.hpp:250
@ TYPE_INVALID
Definition Preset.hpp:245
@ TYPE_PRINT
Definition Preset.hpp:246
@ TYPE_FILAMENT
Definition Preset.hpp:248
T * end(Slic3r::Mat< N, M, T > &mat)
Definition Point.hpp:841
zaa_minimize_perimeter_height nozzle_diameter((ConfigOptionBool, reduce_infill_retraction))((ConfigOptionBool
RaycastManager::TrItems::iterator find(RaycastManager::TrItems &items, const RaycastManager::TrKey &key)
Definition RaycastManager.cpp:298

References add_pending_vendor_preset(), BBL_JSON_KEY_INHERITS, BBL_JSON_KEY_TYPE, Slic3r::PresetBundle::find_preset_vendor(), need_add_filaments, need_add_vendors, Slic3r::nozzle_diameter(), PRESET_IOT_FILAMENT_TYPE, PRESET_IOT_PRINT_TYPE, PRESET_IOT_PRINTER_TYPE, Slic3r::Preset::TYPE_FILAMENT, Slic3r::Preset::TYPE_INVALID, Slic3r::Preset::TYPE_PRINT, and Slic3r::Preset::TYPE_PRINTER.

Referenced by add_pending_vendor_preset(), reload_settings(), sync_bundle(), and update_single_bundle().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ apply_keeped_preset_modifications()

void Slic3r::GUI::GUI_App::apply_keeped_preset_modifications ( )
9235{
9236 PrinterTechnology printer_technology = preset_bundle->printers.get_edited_preset().printer_technology();
9237 for (Tab* tab : tabs_list) {
9238 if (tab->supports_printer_technology(printer_technology))
9239 tab->apply_config_from_cache();
9240 }
9241 load_current_presets(false);
9242}
void load_current_presets(bool active_preset_combox=false, bool check_printer_presets=true)
Definition GUI_App.cpp:9375
std::vector< Tab * > tabs_list
Definition GUI_App.hpp:803
static PrinterTechnology printer_technology()
Definition GUI_Factories.cpp:60
PrinterTechnology
Definition Config.hpp:229

References apply_keeped_preset_modifications(), load_current_presets(), preset_bundle, Slic3r::GUI::printer_technology(), and tabs_list.

Referenced by apply_keeped_preset_modifications(), check_and_keep_current_preset_changes(), Slic3r::GUI::ConfigWizard::run(), and Slic3r::GUI::GuideFrame::run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ associate_files()

void Slic3r::GUI::GUI_App::associate_files ( std::wstring extend)
10313{
10314#ifdef WIN32
10315 // MSIX: shell integration is declared in the package manifest; registry
10316 // writes from a packaged process are virtualized and invisible to the shell.
10317 if (is_running_in_msix())
10318 return;
10319 wchar_t app_path[MAX_PATH];
10320 ::GetModuleFileNameW(nullptr, app_path, sizeof(app_path));
10321
10322 std::wstring prog_path = L"\"" + std::wstring(app_path) + L"\"";
10323 std::wstring prog_id = L" Orca.Slicer.1";
10324 std::wstring prog_desc = L"OrcaSlicer";
10325 std::wstring prog_command = prog_path + L" \"%1\"";
10326 std::wstring reg_base = L"Software\\Classes";
10327 std::wstring reg_extension = reg_base + L"\\." + extend;
10328 std::wstring reg_prog_id = reg_base + L"\\" + prog_id;
10329 std::wstring reg_prog_id_command = reg_prog_id + L"\\Shell\\Open\\Command";
10330
10331 bool is_new = false;
10332 is_new |= set_into_win_registry(HKEY_CURRENT_USER, reg_extension.c_str(), prog_id.c_str());
10333 is_new |= set_into_win_registry(HKEY_CURRENT_USER, reg_prog_id.c_str(), prog_desc.c_str());
10334 is_new |= set_into_win_registry(HKEY_CURRENT_USER, reg_prog_id_command.c_str(), prog_command.c_str());
10335 if (is_new)
10336 // notify Windows only when any of the values gets changed
10337 ::SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr);
10338#endif // WIN32
10339}
#define L(s)
Definition ExtrusionEntity.cpp:25
bool is_running_in_msix()
Definition GUI_Utils.cpp:197

References associate_files(), Slic3r::GUI::is_running_in_msix(), and L.

Referenced by associate_files(), on_init_inner(), and open_preferences().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ associate_url()

void Slic3r::GUI::GUI_App::associate_url ( std::wstring url_prefix)
10395{
10396#ifdef WIN32
10397 if (is_running_in_msix())
10398 return;
10399 boost::filesystem::path binary_path(boost::filesystem::canonical(boost::dll::program_location()));
10400 wxString wbinary = from_path(binary_path);
10401 BOOST_LOG_TRIVIAL(info) << "Downloader registration: Path of binary: " << wbinary.ToUTF8().data();
10402
10403 wxString key_string = "\"" + wbinary + "\" \"%1\"";
10404
10405 wxRegKey key_first(wxRegKey::HKCU, L"Software\\Classes\\" + url_prefix);
10406 wxRegKey key_full(wxRegKey::HKCU, L"Software\\Classes\\" + url_prefix + L"\\shell\\open\\command");
10407 if (!key_first.Exists()) {
10408 key_first.Create(false);
10409 }
10410 key_first.SetValue("URL Protocol", "");
10411
10412 if (!key_full.Exists()) {
10413 key_full.Create(false);
10414 }
10415 key_full = key_string;
10416#elif defined(__linux__) && defined(SLIC3R_DESKTOP_INTEGRATION)
10417 DesktopIntegrationDialog::perform_downloader_desktop_integration(into_u8(url_prefix));
10418#endif // WIN32
10419}
wxString from_path(const boost::filesystem::path &path)
Definition GUI.cpp:555
std::string into_u8(const wxString &str)
Definition GUI.cpp:549

References associate_url(), Slic3r::GUI::from_path(), Slic3r::GUI::into_u8(), Slic3r::GUI::is_running_in_msix(), and L.

Referenced by associate_url(), on_init_inner(), and open_preferences().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ bold_font()

const wxFont & Slic3r::GUI::GUI_App::bold_font ( )
inline
531{ return m_bold_font; }
wxFont m_bold_font
Definition GUI_App.hpp:294

References m_bold_font.

◆ can_load_project()

bool Slic3r::GUI::GUI_App::can_load_project ( )
9332{
9333 return true;
9334}

References can_load_project().

Referenced by can_load_project().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cancel_networking_install()

void Slic3r::GUI::GUI_App::cancel_networking_install ( )
2279{
2281 BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": plugin install cancelled!");
2282}
bool m_networking_cancel_update
Definition GUI_App.hpp:333

References m_networking_cancel_update.

◆ canonical_printer_agent_id()

std::string Slic3r::GUI::GUI_App::canonical_printer_agent_id ( const std::string & picked_id)
4270{
4271 return picked_id == resolve_printer_agent_id("") ? std::string() : picked_id;
4272}
std::string resolve_printer_agent_id(const std::string &stored_id) const
Definition GUI_App.cpp:4262

References canonical_printer_agent_id(), and resolve_printer_agent_id().

Referenced by canonical_printer_agent_id().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ catch_error()

bool Slic3r::GUI::GUI_App::catch_error ( std::function< void()> cb,
const std::string & err )
static
5095{
5096 if (!err.empty()) {
5097 if (cb)
5098 cb();
5099 // if (message_dialog)
5100 // message_dialog->(err, "Error", wxOK | wxICON_ERROR);
5101 show_error(/*this*/nullptr, err);
5102 return true;
5103 }
5104 return false;
5105}
void show_error(wxWindow *parent, const wxString &message, bool has_code_excerpts)
Definition GUI.cpp:296

References catch_error(), and Slic3r::GUI::show_error().

Referenced by catch_error().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_and_keep_current_preset_changes()

bool Slic3r::GUI::GUI_App::check_and_keep_current_preset_changes ( const wxString & caption,
const wxString & header,
int action_buttons,
bool * postponed_apply_of_keeped_changes = nullptr )
9252{
9254 bool is_called_from_configwizard = postponed_apply_of_keeped_changes != nullptr;
9255
9256 UnsavedChangesDialog dlg(caption, header, "", action_buttons);
9257 bool no_need_change = dlg.getUpdateItemCount() == 0 ? true : false;
9258 if (!no_need_change && dlg.ShowModal() == wxID_CANCEL)
9259 return false;
9260
9261 auto reset_modifications = [this]() {
9262 //if (is_called_from_configwizard)
9263 // return; // no need to discared changes. It will be done fromConfigWizard closing
9264
9265 PrinterTechnology printer_technology = preset_bundle->printers.get_edited_preset().printer_technology();
9266 for (const Tab* const tab : tabs_list) {
9267 if (tab->supports_printer_technology(printer_technology) && tab->current_preset_is_dirty())
9268 tab->m_presets->discard_current_changes();
9269 }
9270 load_current_presets(false);
9271 };
9272
9273 if (dlg.discard() || no_need_change)
9274 reset_modifications();
9275 else // save selected changes
9276 {
9277 //BBS: add project embedded preset relate logic
9278 const auto& preset_names_and_types = dlg.get_names_and_types();
9279 if (dlg.save_preset()) {
9280 for (const UnsavedChangesDialog::PresetData& nt : preset_names_and_types)
9281 preset_bundle->save_changes_for_preset(nt.name, nt.type, dlg.get_unselected_options(nt.type), nt.save_to_project);
9282
9283 // if we saved changes to the new presets, we should to
9284 // synchronize config.ini with the current selections.
9285 preset_bundle->export_selections(*app_config);
9286
9287 //wxString text = _L_PLURAL("Modifications to the preset have been saved",
9288 // "Modifications to the presets have been saved", preset_names_and_types.size());
9289 //if (!is_called_from_configwizard)
9290 // text += "\n\n" + _L("All modifications will be discarded for new project.");
9291
9292 //MessageDialog(nullptr, text).ShowModal();
9293 reset_modifications();
9294 }
9295 else if (dlg.transfer_changes() && (dlg.has_unselected_options() || is_called_from_configwizard)) {
9296 // execute this part of code only if not all modifications are keeping to the new project
9297 // OR this function is called when ConfigWizard is closed and "Keep modifications" is selected
9298 for (const UnsavedChangesDialog::PresetData& nt : preset_names_and_types) {
9299 Preset::Type type = nt.type;
9300 Tab* tab = get_tab(type);
9301 std::vector<std::string> selected_options = dlg.get_selected_options(type);
9302 if (type == Preset::TYPE_PRINTER) {
9303 auto it = std::find(selected_options.begin(), selected_options.end(), "extruders_count");
9304 if (it != selected_options.end()) {
9305 // erase "extruders_count" option from the list
9306 selected_options.erase(it);
9307 // cache the extruders count
9308 static_cast<TabPrinter*>(tab)->cache_extruder_cnt();
9309 }
9310 }
9311 std::vector<std::string> selected_options2;
9312 std::transform(selected_options.begin(), selected_options.end(), std::back_inserter(selected_options2), [](auto & o) {
9313 auto i = o.find('#');
9314 return i != std::string::npos ? o.substr(0, i) : o;
9315 });
9316 tab->cache_config_diff(selected_options2);
9317 if (!is_called_from_configwizard)
9318 tab->m_presets->discard_current_changes();
9319 }
9320 if (is_called_from_configwizard)
9321 *postponed_apply_of_keeped_changes = true;
9322 else
9324 }
9325 }
9326 }
9327
9328 return true;
9329}
bool has_current_preset_changes() const
Definition GUI_App.cpp:9155
void apply_keeped_preset_modifications()
Definition GUI_App.cpp:9234
Tab * get_tab(Preset::Type type)
Definition GUI_App.cpp:8680

References app_config, apply_keeped_preset_modifications(), Slic3r::GUI::Tab::cache_config_diff(), check_and_keep_current_preset_changes(), Slic3r::GUI::UnsavedChangesDialog::discard(), Slic3r::PresetCollection::discard_current_changes(), Slic3r::GUI::UnsavedChangesDialog::get_names_and_types(), Slic3r::GUI::UnsavedChangesDialog::get_selected_options(), get_tab(), Slic3r::GUI::UnsavedChangesDialog::get_unselected_options(), Slic3r::GUI::UnsavedChangesDialog::getUpdateItemCount(), has_current_preset_changes(), Slic3r::GUI::UnsavedChangesDialog::has_unselected_options(), load_current_presets(), Slic3r::GUI::Tab::m_presets, preset_bundle, Slic3r::GUI::printer_technology(), Slic3r::GUI::UnsavedChangesDialog::save_preset(), Slic3r::GUI::UnsavedChangesDialog::ShowModal(), tabs_list, Slic3r::GUI::UnsavedChangesDialog::transfer_changes(), and Slic3r::Preset::TYPE_PRINTER.

Referenced by check_and_keep_current_preset_changes().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_and_save_current_preset_changes()

bool Slic3r::GUI::GUI_App::check_and_save_current_preset_changes ( const wxString & caption,
const wxString & header,
bool remember_choice = true,
bool use_dont_save_insted_of_discard = false )
9200{
9202 int act_buttons = ActionButtons::SAVE;
9203 if (dont_save_insted_of_discard)
9204 act_buttons |= ActionButtons::DONT_SAVE;
9205 if (remember_choice)
9206 act_buttons |= ActionButtons::REMEMBER_CHOISE;
9207 UnsavedChangesDialog dlg(caption, header, "", act_buttons);
9208 bool no_need_change = dlg.getUpdateItemCount() == 0 ? true : false;
9209 if (!no_need_change && dlg.ShowModal() == wxID_CANCEL)
9210 return false;
9211
9212 if (dlg.save_preset()) // save selected changes
9213 {
9214 //BBS: add project embedded preset relate logic
9215 for (const UnsavedChangesDialog::PresetData& nt : dlg.get_names_and_types())
9216 preset_bundle->save_changes_for_preset(nt.name, nt.type, dlg.get_unselected_options(nt.type), nt.save_to_project);
9217 //for (const std::pair<std::string, Preset::Type>& nt : dlg.get_names_and_types())
9218 // preset_bundle->save_changes_for_preset(nt.first, nt.second, dlg.get_unselected_options(nt.second));
9219
9220 load_current_presets(false);
9221
9222 // if we saved changes to the new presets, we should to
9223 // synchronize config.ini with the current selections.
9224 preset_bundle->export_selections(*app_config);
9225
9226 //MessageDialog(nullptr, _L_PLURAL("Modifications to the preset have been saved",
9227 // "Modifications to the presets have been saved", dlg.get_names_and_types().size())).ShowModal();
9228 }
9229 }
9230
9231 return true;
9232}
@ DONT_SAVE
Definition UnsavedChangesDialog.hpp:254
@ SAVE
Definition UnsavedChangesDialog.hpp:253
@ REMEMBER_CHOISE
Definition UnsavedChangesDialog.hpp:255

References app_config, check_and_save_current_preset_changes(), Slic3r::GUI::DONT_SAVE, Slic3r::GUI::UnsavedChangesDialog::get_names_and_types(), Slic3r::GUI::UnsavedChangesDialog::get_unselected_options(), Slic3r::GUI::UnsavedChangesDialog::getUpdateItemCount(), has_current_preset_changes(), load_current_presets(), preset_bundle, Slic3r::GUI::REMEMBER_CHOISE, Slic3r::GUI::SAVE, Slic3r::GUI::UnsavedChangesDialog::save_preset(), and Slic3r::GUI::UnsavedChangesDialog::ShowModal().

Referenced by check_and_save_current_preset_changes().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_bundle_updates()

void Slic3r::GUI::GUI_App::check_bundle_updates ( )
7790{
7791 if (!m_agent || !m_agent->is_user_login()) return;
7792 auto orca_agent = std::dynamic_pointer_cast<OrcaCloudServiceAgent>(m_agent->get_cloud_agent());
7793 if (!orca_agent) return;
7794
7795 BOOST_LOG_TRIVIAL(info) << "check_bundle_updates: checking for bundle updates";
7796
7797 // Fetch all subscribed bundles from cloud
7798 std::vector<std::pair<std::string, std::string>> subscribed_bundles;
7799 std::vector<std::string> notfound;
7800 std::vector<std::string> unauthorized;
7801 int result = orca_agent->get_subscribed_bundles(&subscribed_bundles,notfound,unauthorized);
7802
7803 if (result != 0) {
7804 BOOST_LOG_TRIVIAL(warning) << "check_bundle_updates: failed to fetch subscribed bundles, result=" << result;
7805 return;
7806 }
7807
7808 if(!notfound.empty())
7809 {
7810 for(auto& n : notfound)
7811 {
7812 std::string text = format(_L("Bundle %s is no longer available."), n);
7813 wxGetApp().plater()->get_notification_manager()->push_notification(NotificationType::CustomNotification,NotificationManager::NotificationLevel::RegularNotificationLevel,text);
7814 }
7815 }
7816 if(!unauthorized.empty())
7817 {
7818 for(auto& i : unauthorized)
7819 {
7820 std::string text = format(_L("Bundle %s access is unauthorized."), i);
7821 wxGetApp().plater()->get_notification_manager()->push_notification(NotificationType::CustomNotification,NotificationManager::NotificationLevel::RegularNotificationLevel,text);
7822 }
7823 }
7824
7825 // Fetch presets for each bundle
7826 std::map<std::string, std::map<std::string, std::map<std::string, std::string>>> subscribed_bundle_presets;
7827 std::map<std::string, BundleMetadata> subscribed_bundle_metadata;
7828
7829 for (const auto& bundle : subscribed_bundles) {
7830 std::map<std::string, std::map<std::string, std::string>> presets;
7831 BundleMetadata metadata;
7832 int preset_result = orca_agent->get_shared_bundle(bundle.first, &presets, &metadata);
7833
7834 if (preset_result == 0) {
7835 subscribed_bundle_presets[bundle.first] = presets;
7836 subscribed_bundle_metadata[bundle.first] = metadata;
7837 } else {
7838 BOOST_LOG_TRIVIAL(warning) << "check_bundle_updates: Failed to get presets for bundle_id=" << bundle.first << ", result=" << preset_result;
7839 // Continue with other bundles even if one fails
7840 }
7841 }
7842
7843 // Iterate through local bundles and check for updates
7844 if (!preset_bundle) return;
7845
7846 int bundles_checked = 0;
7847 int updates_available = 0;
7848
7849 for (auto& [bundle_id, local_metadata] : preset_bundle->bundles.m_bundles) {
7850 // Only check subscribed bundles (those with UUID-style IDs from Orca Cloud)
7851 // Skip external bundles (those with name+timestamp IDs)
7852 if (!local_metadata.is_subscribed) {
7853 continue;
7854 }
7855
7856 // Find corresponding remote metadata
7857 auto remote_it = subscribed_bundle_metadata.find(bundle_id);
7858 if (remote_it == subscribed_bundle_metadata.end()) {
7859 BOOST_LOG_TRIVIAL(info) << "check_bundle_updates: bundle " << bundle_id << " not found in remote subscriptions";
7860 continue;
7861 }
7862
7863 const auto& remote_metadata = remote_it->second;
7864
7865 // Compare versions using Semver
7866 auto local_version = Semver::parse(local_metadata.version);
7867 auto remote_version = Semver::parse(remote_metadata.version);
7868
7869 if (!local_version || !remote_version) {
7870 BOOST_LOG_TRIVIAL(warning) << "check_bundle_updates: failed to parse versions for bundle " << bundle_id
7871 << " (local: " << local_metadata.version << ", remote: " << remote_metadata.version << ")";
7872 continue;
7873 }
7874
7875 bundles_checked++;
7876
7877 // Update the runtime-only flag if remote version is newer
7878 if (remote_version > local_version) {
7879 local_metadata.update_available = true;
7880 updates_available++;
7881 BOOST_LOG_TRIVIAL(info) << "check_bundle_updates: bundle " << bundle_id << " (" << local_metadata.name
7882 << ") has update available: local=" << local_metadata.version
7883 << ", remote=" << remote_metadata.version;
7884 } else {
7885 local_metadata.update_available = false;
7886 }
7887 }
7888
7889 BOOST_LOG_TRIVIAL(info) << "check_bundle_updates: checked " << bundles_checked
7890 << " bundles, found " << updates_available << " updates available";
7891}
#define _L(s)
Definition OBJ.cpp:34
@ RegularNotificationLevel
Definition NotificationManager.hpp:216
static boost::optional< Semver > parse(const std::string &str)
Definition Semver.hpp:63
@ CustomNotification
Definition NotificationManager.hpp:66
std::string format(const char *fmt, TArgs &&... args)
Definition format.hpp:36

References _L, check_bundle_updates(), Slic3r::GUI::CustomNotification, Slic3r::GUI::format(), m_agent, Slic3r::Semver::parse(), preset_bundle, and Slic3r::GUI::NotificationManager::RegularNotificationLevel.

Referenced by check_bundle_updates().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_config_updates_from_updater()

void Slic3r::GUI::GUI_App::check_config_updates_from_updater ( )
inline
861{ check_updates(false); }
void check_updates(const bool verbose)
Definition GUI_App.cpp:10184

References check_updates().

Here is the call graph for this function:

◆ check_legacy_user_filament_presets()

void Slic3r::GUI::GUI_App::check_legacy_user_filament_presets ( bool by_user)
7088{
7089 // One check at a time: the startup check can come due while the manual one is open, and on macOS the menu bar
7090 // stays usable while a modal dialog is up.
7092 return;
7093 if (!by_user && app_config->get_bool("legacy_user_filament_presets_dont_remind"))
7094 return;
7095 // The local copies may be older than the cloud ones another machine changed: migrating them would push changes
7096 // made against stale copies and conflict with the cloud. The startup check waits for the presets to be pulled.
7097 if (!by_user && m_user_preset_pull_pending) {
7099 return;
7100 }
7101 // This check also answers a startup check that is still waiting.
7104 ScopeGuard running_guard([this] { m_legacy_filament_check_running = false; });
7105
7106 const std::vector<LegacyUserFilamentPreset> legacy_presets = preset_bundle->legacy_user_filament_presets();
7107 if (legacy_presets.empty()) {
7108 if (by_user)
7109 MessageDialog(mainframe, _L("All your filament presets are available on the printers they were made for."),
7110 _L("Migrate Filament Presets"), wxOK | wxICON_INFORMATION).ShowModal();
7111 return;
7112 }
7113
7114 wxString message = _L("OrcaSlicer 2.5.0 restructured many system filament presets to fix incorrect profiles and prepare "
7115 "for future features. As a result, the presets below no longer show on some printers they were made "
7116 "for. Sorry for the trouble; this is a one-time fix.\n\n"
7117 "Add those printers back to your presets now? Your presets are backed up first. You can also do this "
7118 "later from Help > Migrate Filament Presets.") + "\n";
7119 for (const LegacyUserFilamentPreset &legacy : legacy_presets) {
7120 message += "\n" + format_wxstr(_L("%1% (based on %2%)"), legacy.preset, legacy.parent);
7121 for (const std::string &printer : legacy.printers)
7122 message += "\n " + from_u8(printer);
7123 }
7124 RichMessageDialog dlg(mainframe, message, _L("Migrate Filament Presets"), wxYES | wxNO | wxICON_QUESTION);
7125 if (!by_user)
7126 dlg.ShowCheckBox(_L("Don't remind me again"));
7127 const bool migrate = dlg.ShowModal() == wxID_YES;
7128 if (dlg.IsCheckBoxChecked())
7129 app_config->set_bool("legacy_user_filament_presets_dont_remind", true);
7130 if (!migrate)
7131 return;
7132
7133 const PresetBundle::LegacyUserFilamentPresetMigration migration = preset_bundle->migrate_legacy_user_filament_presets(legacy_presets);
7134 const std::string &backup = migration.backup;
7135 const std::vector<std::string> &failed = migration.failed;
7136 if (backup.empty()) {
7137 show_error(mainframe, _L("Your presets could not be backed up, so they were not migrated."));
7138 return;
7139 }
7140 if (!migration.locked) {
7141 // The lock is also refused for a while after a miss, and when the lock file itself cannot be opened.
7142 show_error(mainframe, _L("The user presets folder could not be locked, so nothing was migrated. Another OrcaSlicer "
7143 "instance may be saving presets; try again later from Help > Migrate Filament Presets."));
7144 return;
7145 }
7146 if (failed.size() == legacy_presets.size()) {
7147 show_error(mainframe, format_wxstr(_L("Your filament presets could not be migrated. A backup of your presets was saved to:\n%1%"), backup));
7148 return;
7149 }
7150 // Ask the sync loop to push on its next pass instead of its next 60 s round, which shortens the time the migrated
7151 // presets stay unpushed.
7152 m_sync_user_presets_now.store(true, std::memory_order_release);
7154 mainframe->update_side_preset_ui();
7155 for (auto tab : tabs_list) {
7156 tab->reload_config();
7157 tab->update_changed_ui();
7158 }
7159
7160 message = format_wxstr(_L("Your filament presets were migrated. Select them again in the filament list where you used them.\n\n"
7161 "A backup of your presets was saved to:\n%1%"), backup);
7162 if (!failed.empty()) {
7163 message += "\n\n" + _L("These presets could not be migrated:");
7164 for (const std::string &name : failed)
7165 message += "\n" + from_u8(name);
7166 }
7167 MessageDialog(mainframe, message, _L("Migrate Filament Presets"), wxOK | (failed.empty() ? wxICON_INFORMATION : wxICON_WARNING)).ShowModal();
7168}
bool m_user_preset_pull_pending
Definition GUI_App.hpp:358
bool m_legacy_filament_check_running
Definition GUI_App.hpp:360
bool m_legacy_filament_check_due
Definition GUI_App.hpp:359
MainFrame * mainframe
Definition GUI_App.hpp:790
std::atomic< bool > m_sync_user_presets_now
Definition GUI_App.hpp:357
wxString format_wxstr(const char *fmt, TArgs &&... args)
Definition format.hpp:22
wxString from_u8(const std::string &str)
Definition GUI.cpp:544
@ Never
Definition Preset.hpp:523

References _L, app_config, Slic3r::PresetBundle::LegacyUserFilamentPresetMigration::backup, check_legacy_user_filament_presets(), Slic3r::PresetBundle::LegacyUserFilamentPresetMigration::failed, Slic3r::GUI::format_wxstr(), Slic3r::GUI::from_u8(), Slic3r::GUI::RichMessageDialog::IsCheckBoxChecked(), Slic3r::PresetBundle::LegacyUserFilamentPresetMigration::locked, m_legacy_filament_check_due, m_legacy_filament_check_running, m_sync_user_presets_now, m_user_preset_pull_pending, mainframe, Slic3r::Never, preset_bundle, Slic3r::GUI::show_error(), Slic3r::GUI::RichMessageDialog::ShowCheckBox(), Slic3r::GUI::DPIAware< P >::ShowModal(), Slic3r::GUI::RichMessageDialog::ShowModal(), and tabs_list.

Referenced by check_legacy_user_filament_presets(), post_init(), and start_sync_user_preset().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_login()

bool Slic3r::GUI::GUI_App::check_login ( const std::string & provider = ORCA_CLOUD_PROVIDER)
5336{
5337 bool result = false;
5338 if (m_agent) {
5339 result = m_agent->is_user_login(provider);
5340 }
5341
5342 if (!result) {
5343 ShowUserLogin(true, provider);
5344 }
5345 return result;
5346}
void ShowUserLogin(bool show=true, const std::string &provider=ORCA_CLOUD_PROVIDER)
Definition GUI_App.cpp:5053

References check_login(), m_agent, and ShowUserLogin().

Referenced by check_login(), and request_project_download().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_networking_version()

bool Slic3r::GUI::GUI_App::check_networking_version ( )
2231{
2232 std::string network_ver = Slic3r::NetworkAgent::get_version();
2233 if (!network_ver.empty()) {
2234 BOOST_LOG_TRIVIAL(info) << "get_network_agent_version=" << network_ver;
2235 }
2236
2237 std::string studio_ver;
2240 } else if (app_config) {
2241 std::string user_version = app_config->get_network_plugin_version();
2242 studio_ver = user_version.empty() ? get_latest_network_version() : user_version;
2243 } else {
2244 studio_ver = get_latest_network_version();
2245 }
2246
2247 BOOST_LOG_TRIVIAL(info) << "check_networking_version: network_ver=" << network_ver << ", expected=" << studio_ver;
2248
2249 // A configured version outside the whitelisted series must never pass as compatible,
2250 // even if it matches the loaded library - its ABI does not match this build.
2253 return false;
2254 }
2255
2256 if (network_ver.length() >= 8 && studio_ver.length() >= 8) {
2257 if (network_ver.substr(0,8) == studio_ver.substr(0,8)) {
2259 return true;
2260 }
2261 }
2262
2264 return false;
2265}
#define BAMBU_NETWORK_AGENT_VERSION_LEGACY
Definition AppConfig.hpp:65
std::string get_latest_network_version() const
Definition GUI_App.cpp:2135
bool m_networking_compatible
Definition GUI_App.hpp:331
bool use_legacy_network_plugin() const
Definition GUI_App.cpp:2267
static std::string get_version()
Definition NetworkAgent.cpp:84
bool is_supported_network_version(const std::string &version)
Definition bambu_networking.hpp:479

References app_config, BAMBU_NETWORK_AGENT_VERSION_LEGACY, get_latest_network_version(), Slic3r::NetworkAgent::get_version(), Slic3r::is_supported_network_version(), m_networking_compatible, and use_legacy_network_plugin().

Referenced by on_init_network().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_new_version()

void Slic3r::GUI::GUI_App::check_new_version ( bool show_tips = false,
int by_user = 0 )
6219{
6220 return; // orca: not used, see check_new_version_sf
6221 std::string platform = "windows";
6222
6223#ifdef __WINDOWS__
6224 platform = "windows";
6225#endif
6226#ifdef __APPLE__
6227 platform = "macos";
6228#endif
6229#ifdef __LINUX__
6230 platform = "linux";
6231#endif
6232 std::string query_params = (boost::format("?name=slicer&version=%1%&guide_version=%2%")
6233 % VersionInfo::convert_full_version(SLIC3R_VERSION)
6235 ).str();
6236
6237 std::string url = get_http_url(app_config->get_country_code()) + query_params;
6239
6240 http.header("accept", "application/json")
6241 .timeout_connect(TIMEOUT_CONNECT)
6242 .timeout_max(TIMEOUT_RESPONSE)
6243 .on_complete([this, show_tips, by_user](std::string body, unsigned) {
6244 try {
6245 json j = json::parse(body);
6246 if (j.contains("message")) {
6247 if (j["message"].get<std::string>() == "success") {
6248 if (j.contains("software")) {
6249 if (j["software"].empty() && show_tips) {
6250 this->no_new_version();
6251 }
6252 else {
6253 if (j["software"].contains("url")
6254 && j["software"].contains("version")
6255 && j["software"].contains("description")) {
6256 version_info.url = j["software"]["url"].get<std::string>();
6257 version_info.version_str = j["software"]["version"].get<std::string>();
6258 version_info.description = j["software"]["description"].get<std::string>();
6259 }
6260 if (j["software"].contains("force_update")) {
6261 version_info.force_upgrade = j["software"]["force_update"].get<bool>();
6262 }
6263 CallAfter([this, show_tips, by_user](){
6264 this->check_update(show_tips, by_user);
6265 });
6266 }
6267 }
6268 }
6269 }
6270 }
6271 catch (...) {
6272 ;
6273 }
6274 })
6275 .on_error([this](std::string body, std::string error, unsigned int status) {
6276 handle_http_error(status, body);
6277 BOOST_LOG_TRIVIAL(error) << "check new version error" << body;
6278 }).perform();
6279}
#define TIMEOUT_RESPONSE
Definition GUI_App.hpp:53
#define TIMEOUT_CONNECT
Definition GUI_App.hpp:52
void check_update(bool show_tips, int by_user)
Definition GUI_App.cpp:6192
std::string get_http_url(std::string country_code, std::string path={})
Definition GUI_App.cpp:1329
void handle_http_error(unsigned int status, std::string body, const std::string &provider="")
Definition GUI_App.cpp:5792
void no_new_version()
Definition GUI_App.cpp:6926
VersionInfo version_info
Definition GUI_App.hpp:347
static std::string convert_full_version(std::string short_version)
Definition GUI_App.cpp:396
static Http get(std::string url)
Definition Http.cpp:886
bool contains(const std::vector< T > &vector, const Point &point)
Definition Geometry.cpp:55
nlohmann::json json
Definition AssembleList.cpp:42
@ http
Definition IPrinterAgent.hpp:64
@ Http
Definition PluginAuditManager.hpp:49
Platform platform()
Definition Platform.cpp:103
bool empty(const BoundingBoxBase< PointType, PointsType > &bb)
Definition BoundingBox.hpp:273

References app_config, check_new_version(), check_update(), Slic3r::Geometry::contains(), Slic3r::GUI::VersionInfo::convert_full_version(), Slic3r::empty(), Slic3r::Http::get(), get_http_url(), handle_http_error(), Slic3r::http, no_new_version(), Slic3r::platform(), TIMEOUT_CONNECT, TIMEOUT_RESPONSE, and version_info.

Referenced by check_new_version().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_new_version_sf()

void Slic3r::GUI::GUI_App::check_new_version_sf ( bool show_tips = false,
int by_user = 0 )
6526{
6527 AppConfig* app_config = wxGetApp().app_config;
6528 bool check_stable_only = app_config->get_bool("check_stable_update_only");
6529 auto version_check_url = app_config->version_check_url();
6530
6531 UpdaterQuery query{
6537 };
6538
6539 const std::string query_string = build_updater_query(query);
6540 if (!query_string.empty()) {
6541 const bool has_query = version_check_url.find('?') != std::string::npos;
6542 if (!has_query)
6543 version_check_url.push_back('?');
6544 else if (!version_check_url.empty() && version_check_url.back() != '&' && version_check_url.back() != '?')
6545 version_check_url.push_back('&');
6546 version_check_url += query_string;
6547 }
6548
6549 auto http = Http::get(version_check_url);
6550 maybe_attach_updater_signature(http, query_string, version_check_url);
6551
6552 http.header("accept", "application/vnd.github.v3+json")
6553 .timeout_connect(5)
6554 .timeout_max(10)
6555 .on_error([&](std::string body, std::string error, unsigned http_status) {
6556 (void)body;
6557 BOOST_LOG_TRIVIAL(error) << format("Error getting: `%1%`: HTTP %2%, %3%", "check_new_version_sf", http_status,
6558 error);
6559 })
6560 .on_complete([this, by_user, check_stable_only](std::string body, unsigned http_status) {
6561 if (http_status != 200)
6562 return;
6563 try {
6564 boost::trim(body);
6565 if (body.empty()) {
6566 if (by_user != 0)
6567 this->no_new_version();
6568 return;
6569 }
6570
6571 boost::property_tree::ptree root;
6572 std::stringstream json_stream(body);
6573 boost::property_tree::read_json(json_stream, root);
6574
6575 std::regex matcher("[0-9]+\\.[0-9]+(\\.[0-9]+)*(-[A-Za-z0-9]+)?(\\+[A-Za-z0-9]+)?");
6576 Semver current_version = get_version(SoftFever_VERSION, matcher);
6577 Semver best_pre(0, 0, 0);
6578 Semver best_release(0, 0, 0);
6579 bool best_pre_valid = false;
6580 bool best_release_valid = false;
6581 std::string best_pre_url;
6582 std::string best_release_url;
6583 std::string best_release_content;
6584 std::string best_pre_content;
6585
6586 auto consider_release = [&](const boost::property_tree::ptree& node) {
6587 auto tag_opt = node.get_optional<std::string>("tag_name");
6588 if (!tag_opt)
6589 return;
6590
6591 std::string tag = *tag_opt;
6592 if (!tag.empty() && tag.front() == 'v')
6593 tag.erase(0, 1);
6594
6595 Semver tag_version = get_version(tag, matcher);
6596 if (!tag_version.valid())
6597 return;
6598
6599 const bool is_prerelease = node.get_optional<bool>("prerelease").get_value_or(false);
6600 const std::string html_url = node.get_optional<std::string>("html_url").get_value_or(std::string());
6601 const std::string body_copy = node.get_optional<std::string>("body").get_value_or(std::string());
6602
6603 if (is_prerelease) {
6604 if (!best_pre_valid || best_pre < tag_version) {
6605 best_pre = tag_version;
6606 best_pre_url = html_url;
6607 best_pre_content = body_copy;
6608 best_pre_valid = true;
6609 }
6610 } else {
6611 if (!best_release_valid || best_release < tag_version) {
6612 best_release = tag_version;
6613 best_release_url = html_url;
6614 best_release_content = body_copy;
6615 best_release_valid = true;
6616 }
6617 }
6618 };
6619
6620 if (root.get_optional<std::string>("tag_name")) {
6621 consider_release(root);
6622 } else {
6623 for (const auto& child : root)
6624 consider_release(child.second);
6625 }
6626
6627 if (!best_release_valid && !best_pre_valid) {
6628 if (by_user != 0)
6629 this->no_new_version();
6630 return;
6631 }
6632
6633 if (best_pre_valid && best_release_valid && best_pre < best_release) {
6634 best_pre = best_release;
6635 best_pre_url = best_release_url;
6636 best_pre_content = best_release_content;
6637 best_pre_valid = true;
6638 }
6639
6640 const bool prefer_release = check_stable_only || !best_pre_valid;
6641 const Semver& chosen_version = prefer_release ? best_release : best_pre;
6642 const bool chosen_valid = prefer_release ? best_release_valid : best_pre_valid;
6643
6644 if (!chosen_valid) {
6645 if (by_user != 0)
6646 this->no_new_version();
6647 return;
6648 }
6649
6650 if (current_version.valid() && chosen_version <= current_version) {
6651 if (by_user != 0)
6652 this->no_new_version();
6653 return;
6654 }
6655
6656 version_info.url = prefer_release ? best_release_url : best_pre_url;
6657 version_info.version_str = prefer_release ? best_release.to_string_sf() : best_pre.to_string_sf();
6658 version_info.description = prefer_release ? best_release_content : best_pre_content;
6659 version_info.force_upgrade = false;
6660
6661 wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_VERSION_ONLINE);
6662 evt->SetString((prefer_release ? best_release : best_pre).to_string());
6663 GUI::wxGetApp().QueueEvent(evt);
6664 } catch (...) {}
6665 });
6666
6667 http.perform();
6668}
void maybe_attach_updater_signature(Http &http, const std::string &canonical_query, const std::string &request_url)
Definition GUI_App.cpp:6491
std::string detect_updater_iid(AppConfig *config)
Definition GUI_App.cpp:6350
std::string detect_updater_version()
Definition GUI_App.cpp:6345
std::string build_updater_query(const UpdaterQuery &query)
Definition GUI_App.cpp:6378
std::string detect_updater_os_info()
Definition GUI_App.cpp:6306
static std::string to_string(libvgcode::EMoveType type)
Definition GCodeViewer.cpp:377
Semver get_version(const std::string &str, const std::regex &regexp)
Definition GUI_App.cpp:6282
std::string platform_os_type()
Definition Platform.cpp:113
std::string platform_architecture()
Definition Platform.cpp:126

References app_config, check_new_version_sf(), Slic3r::GUI::format(), Slic3r::Http::get(), Slic3r::GUI::get_version(), Slic3r::http, no_new_version(), Slic3r::platform_architecture(), Slic3r::platform_os_type(), Slic3r::GUI::to_string(), Slic3r::Semver::to_string_sf(), Slic3r::Semver::valid(), and version_info.

Referenced by check_new_version_sf(), and post_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_older_app_config()

bool Slic3r::GUI::GUI_App::check_older_app_config ( Semver current_version,
bool backup )
private
2839{
2840 //BBS: current no need these logic
2841 return false;
2842}

References check_older_app_config().

Referenced by check_older_app_config().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_preset_parent_available()

bool Slic3r::GUI::GUI_App::check_preset_parent_available ( const std::pair< std::string, std::map< std::string, std::string > > & preset_data)
7366{
7367 auto it = preset_data.second.find(BBL_JSON_KEY_INHERITS);
7368 if (it == preset_data.second.end() || it->second.empty())
7369 return true;
7370 const std::string& inherits_name = it->second;
7371 // If contains "fdm_", "@System", and "@base", is a common base template that doesn't need to be installed
7372 if (inherits_name.find("fdm_") != std::string::npos || inherits_name.find("@System") != std::string::npos || inherits_name.find("@base") != std::string::npos)
7373 return true;
7374
7375 if (preset_data.second.at(BBL_JSON_KEY_TYPE) == PRESET_IOT_PRINT_TYPE)
7376 return preset_bundle->prints.find_preset2(inherits_name) != nullptr;
7377 else if (preset_data.second.at(BBL_JSON_KEY_TYPE) == PRESET_IOT_PRINTER_TYPE)
7378 return preset_bundle->printers.find_preset2(inherits_name) != nullptr;
7379 else if (preset_data.second.at(BBL_JSON_KEY_TYPE) == PRESET_IOT_FILAMENT_TYPE)
7380 return preset_bundle->filaments.find_preset2(inherits_name) != nullptr;
7381 return true;
7382}

References BBL_JSON_KEY_INHERITS, BBL_JSON_KEY_TYPE, check_preset_parent_available(), preset_bundle, PRESET_IOT_FILAMENT_TYPE, PRESET_IOT_PRINT_TYPE, and PRESET_IOT_PRINTER_TYPE.

Referenced by check_preset_parent_available(), reload_settings(), sync_bundle(), and update_single_bundle().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_print_host_queue()

bool Slic3r::GUI::GUI_App::check_print_host_queue ( )
9337{
9338 wxString dirty;
9339 std::vector<std::pair<std::string, std::string>> jobs;
9340 // Get ongoing jobs from dialog
9341 mainframe->m_printhost_queue_dlg->get_active_jobs(jobs);
9342 if (jobs.empty())
9343 return true;
9344 // Show dialog
9345 wxString job_string = wxString();
9346 for (const auto& job : jobs) {
9347 job_string += format_wxstr(" %1% : %2% \n", job.first, job.second);
9348 }
9349 wxString message;
9350 message += _(L("The uploads are still ongoing")) + ":\n\n" + job_string +"\n" + _(L("Stop them and continue anyway?"));
9351 //wxMessageDialog dialog(mainframe,
9352 MessageDialog dialog(mainframe,
9353 message,
9354 wxString(SLIC3R_APP_NAME) + " - " + _(L("Ongoing uploads")),
9355 wxICON_QUESTION | wxYES_NO | wxNO_DEFAULT);
9356 if (dialog.ShowModal() == wxID_YES)
9357 return true;
9358
9359 // TODO: If already shown, bring forward
9360 mainframe->m_printhost_queue_dlg->Show();
9361 return false;
9362}
#define _(s)
Definition 3mf.cpp:306

References _, check_print_host_queue(), Slic3r::GUI::format_wxstr(), L, mainframe, and Slic3r::GUI::DPIAware< P >::ShowModal().

Referenced by check_print_host_queue().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_printer_presets()

void Slic3r::GUI::GUI_App::check_printer_presets ( )
4907{
4908//BBS
4909#if 0
4910 std::vector<std::string> preset_names = PhysicalPrinter::presets_with_print_host_information(preset_bundle->printers);
4911 if (preset_names.empty())
4912 return;
4913
4914 // BBS: remove "print host upload" message dialog
4915 preset_bundle->physical_printers.load_printers_from_presets(preset_bundle->printers);
4916#endif
4917}
static std::vector< std::string > presets_with_print_host_information(const PrinterPresetCollection &printer_presets)
Definition Preset.cpp:4577

References check_printer_presets(), preset_bundle, and Slic3r::PhysicalPrinter::presets_with_print_host_information().

Referenced by check_printer_presets(), and load_current_presets().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_privacy_update()

bool Slic3r::GUI::GUI_App::check_privacy_update ( )
6842{
6843 if (privacy_version_info.version_str.empty() || privacy_version_info.description.empty()
6844 || privacy_version_info.url.empty()) {
6845 return false;
6846 }
6847
6848 std::string local_privacy_ver = app_config->get("privacy_version");
6849 auto curr_version = Semver::parse(local_privacy_ver);
6850 auto remote_version = Semver::parse(privacy_version_info.version_str);
6851 if (curr_version && remote_version) {
6852 if (*remote_version > *curr_version || app_config->get("privacy_update_checked") != "true") {
6853 return true;
6854 }
6855 }
6856 return false;
6857}
VersionInfo privacy_version_info
Definition GUI_App.hpp:348

References app_config, check_privacy_update(), Slic3r::Semver::parse(), and privacy_version_info.

Referenced by check_privacy_update(), and on_check_privacy_update().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_privacy_version()

void Slic3r::GUI::GUI_App::check_privacy_version ( int online_login = 0,
const std::string & provider = ORCA_CLOUD_PROVIDER )
6872{
6873 if (app_config->get_stealth_mode()) {
6874 request_user_handle(online_login);
6875 return;
6876 }
6877
6878 std::string query_params = "?policy/privacy=00.00.00.00";
6879 std::string url = get_http_url(app_config->get_country_code()) + query_params;
6881
6882 http.header("accept", "application/json")
6883 .timeout_connect(TIMEOUT_CONNECT)
6884 .timeout_max(TIMEOUT_RESPONSE)
6885 .on_complete([this, online_login, provider](std::string body, unsigned) {
6886 try {
6887 json j = json::parse(body);
6888 if (j.contains("message")) {
6889 if (j["message"].get<std::string>() == "success") {
6890 if (j.contains("resources")) {
6891 for (auto it = j["resources"].begin(); it != j["resources"].end(); it++) {
6892 if (it->contains("type")) {
6893 if ((*it)["type"] == std::string("policy/privacy")
6894 && it->contains("version")
6895 && it->contains("description")
6896 && it->contains("url")
6897 && it->contains("force_update")) {
6898 privacy_version_info.version_str = (*it)["version"].get<std::string>();
6899 privacy_version_info.description = (*it)["description"].get<std::string>();
6900 privacy_version_info.url = (*it)["url"].get<std::string>();
6901 privacy_version_info.force_upgrade = (*it)["force_update"].get<bool>();
6902 break;
6903 }
6904 }
6905 }
6906 CallAfter([this, online_login, provider]() {
6907 auto evt = new wxCommandEvent(EVT_CHECK_PRIVACY_VER);
6908 evt->SetInt(online_login);
6909 evt->SetString(wxString::FromUTF8(provider));
6910 wxQueueEvent(this, evt);
6911 });
6912 }
6913 }
6914 }
6915 }
6916 catch (...) {
6917 request_user_handle(online_login, provider);
6918 }
6919 })
6920 .on_error([this, online_login, provider](std::string body, std::string error, unsigned int status) {
6921 request_user_handle(online_login, provider);
6922 BOOST_LOG_TRIVIAL(error) << "check privacy version error" << body;
6923 }).perform();
6924}
void request_user_handle(int online_login=0, const std::string &provider=ORCA_CLOUD_PROVIDER)
Definition GUI_App.cpp:5348
T * begin(Slic3r::Mat< N, M, T > &mat)
Definition Point.hpp:838

References app_config, check_privacy_version(), Slic3r::Http::get(), get_http_url(), Slic3r::http, privacy_version_info, request_user_handle(), TIMEOUT_CONNECT, and TIMEOUT_RESPONSE.

Referenced by check_privacy_version(), and on_user_login().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_track_enable()

void Slic3r::GUI::GUI_App::check_track_enable ( )
6157{
6158 // Orca: telemetry only exists on the BBL cloud agent; always disable it.
6159 if (m_agent) {
6160 m_agent->track_enable(false);
6161 m_agent->track_remove_files();
6162 }
6163}

References check_track_enable(), and m_agent.

Referenced by check_track_enable(), on_init_network(), and on_user_login().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_update()

void Slic3r::GUI::GUI_App::check_update ( bool show_tips,
int by_user )
6193{
6194 if (version_info.version_str.empty()) return;
6195 if (version_info.url.empty()) return;
6196
6197 auto curr_version = Semver::parse(SLIC3R_VERSION);
6198 auto remote_version = Semver::parse(version_info.version_str);
6199 if (curr_version && remote_version && (*remote_version > *curr_version)) {
6200 if (version_info.force_upgrade) {
6201 wxGetApp().app_config->set_bool("force_upgrade", version_info.force_upgrade);
6202 wxGetApp().app_config->set("upgrade", "force_upgrade", true);
6203 wxGetApp().app_config->set("upgrade", "description", version_info.description);
6204 wxGetApp().app_config->set("upgrade", "version", version_info.version_str);
6205 wxGetApp().app_config->set("upgrade", "url", version_info.url);
6206 GUI::wxGetApp().enter_force_upgrade();
6207 }
6208 else {
6209 GUI::wxGetApp().request_new_version(by_user);
6210 }
6211 } else {
6212 wxGetApp().app_config->set("upgrade", "force_upgrade", false);
6213 if (show_tips)
6214 this->no_new_version();
6215 }
6216}

References check_update(), no_new_version(), Slic3r::Semver::parse(), and version_info.

Referenced by check_new_version(), and check_update().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_updates()

void Slic3r::GUI::GUI_App::check_updates ( const bool verbose)
private
10185{
10186 PresetUpdater::UpdateResult updater_result;
10187 try {
10189 if (updater_result == PresetUpdater::R_INCOMPAT_EXIT) {
10190 mainframe->Close();
10191 }
10192 else if (updater_result == PresetUpdater::R_INCOMPAT_CONFIGURED) {
10193 m_app_conf_exists = true;
10194 }
10195 else if (verbose && updater_result == PresetUpdater::R_NOOP) {
10196 MsgNoUpdates dlg;
10197 dlg.ShowModal();
10198 }
10199 }
10200 catch (const std::exception & ex) {
10201 show_error(nullptr, ex.what());
10202 }
10203}
bool m_app_conf_exists
Definition GUI_App.hpp:268
UpdateResult
Definition PresetUpdater.hpp:37
@ R_NOOP
Definition PresetUpdater.hpp:38
@ R_INCOMPAT_EXIT
Definition PresetUpdater.hpp:39
@ R_INCOMPAT_CONFIGURED
Definition PresetUpdater.hpp:40
@ SHOW_TEXT_BOX
Definition PresetUpdater.hpp:48
@ SHOW_NOTIFICATION
Definition PresetUpdater.hpp:49

References app_config, check_updates(), m_app_conf_exists, mainframe, preset_updater, Slic3r::PresetUpdater::R_INCOMPAT_CONFIGURED, Slic3r::PresetUpdater::R_INCOMPAT_EXIT, Slic3r::PresetUpdater::R_NOOP, Slic3r::GUI::show_error(), Slic3r::PresetUpdater::SHOW_NOTIFICATION, Slic3r::PresetUpdater::SHOW_TEXT_BOX, and Slic3r::GUI::DPIAware< P >::ShowModal().

Referenced by check_config_updates_from_updater(), and check_updates().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_url_association()

bool Slic3r::GUI::GUI_App::check_url_association ( std::wstring url_prefix,
std::wstring & reg_bin )
10376{
10377 reg_bin = L"";
10378#ifdef WIN32
10379 wxRegKey key_full(wxRegKey::HKCU, L"Software\\Classes\\" + url_prefix + L"\\shell\\open\\command");
10380 if (!key_full.Exists()) {
10381 return false;
10382 }
10383 wxString reg_value = key_full.QueryDefaultValue();
10384 reg_bin = reg_value.ToStdWstring();
10385
10386 boost::filesystem::path binary_path(boost::filesystem::canonical(boost::dll::program_location()));
10387 wxString key_string = "\"" + from_path(binary_path) + "\" \"%1\"";
10388 return key_string == reg_value;
10389#else
10390 return false;
10391#endif // WIN32
10392}

References check_url_association(), Slic3r::GUI::from_path(), and L.

Referenced by check_url_association().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ checked_tab()

bool Slic3r::GUI::GUI_App::checked_tab ( Tab * tab)
9365{
9366 bool ret = true;
9367 if (find(tabs_list.begin(), tabs_list.end(), tab) == tabs_list.end() &&
9368 find(model_tabs_list.begin(), model_tabs_list.end(), tab) == model_tabs_list.end())
9369 ret = false;
9370 return ret;
9371}
std::vector< Tab * > model_tabs_list
Definition GUI_App.hpp:804

References checked_tab(), model_tabs_list, and tabs_list.

Referenced by checked_tab().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ CleanUp()

void Slic3r::GUI::GUI_App::CleanUp ( )
override
2967{
2968 // OnExit() does not run when OnInit() fails, and m_agent is then still set. Stop the check before
2969 // wxApp::CleanUp() resets wxTheApp, which a result posted from the worker would still be using.
2971 wxApp::CleanUp();
2972}
void stop_orca_health_check(NetworkAgent *agent)
Definition GUI_App.cpp:1916

References CleanUp(), and m_agent.

Referenced by CleanUp().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cloud_webview_handoff()

wxString Slic3r::GUI::GUI_App::cloud_webview_handoff ( const std::string & next = std::string())
6002{
6003 // The cloud pane loads the Start URL, not a token: the page checks the webview's own session
6004 // and asks for a handoff itself (guide §4). Signed out, user_id is omitted and the page will
6005 // post request_web_session, which is what opens the desktop login dialog.
6006 auto orca = get_orca_cloud_agent(m_agent);
6007 if (!orca)
6008 return {};
6009 return from_u8(orca->build_web_session_start_url(next));
6010}
static std::shared_ptr< OrcaCloudServiceAgent > get_orca_cloud_agent(NetworkAgent *agent)
Definition GUI_App.cpp:338

References cloud_webview_handoff(), Slic3r::GUI::from_u8(), Slic3r::GUI::get_orca_cloud_agent(), and m_agent.

Referenced by cloud_webview_handoff(), on_user_login_handle(), and open_orca_cloud().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ code_font()

const wxFont & Slic3r::GUI::GUI_App::code_font ( )
inline
533{ return m_code_font; }
wxFont m_code_font
Definition GUI_App.hpp:296

References m_code_font.

◆ config_wizard_startup()

bool Slic3r::GUI::GUI_App::config_wizard_startup ( )
private
10165{
10166 if (!m_app_conf_exists || preset_bundle->printers.only_default_printers()) {
10167 BOOST_LOG_TRIVIAL(info) << "run wizard...";
10169 BOOST_LOG_TRIVIAL(info) << "finished run wizard";
10170 return true;
10171 } /*else if (get_app_config()->legacy_datadir()) {
10172 // Looks like user has legacy pre-vendorbundle data directory,
10173 // explain what this is and run the wizard
10174
10175 MsgDataLegacy dlg;
10176 dlg.ShowModal();
10177
10178 run_wizard(ConfigWizard::RR_DATA_LEGACY);
10179 return true;
10180 }*/
10181 return false;
10182}
@ RR_DATA_EMPTY
Definition ConfigWizard.hpp:24
bool run_wizard(ConfigWizard::RunReason reason, ConfigWizard::StartPage start_page=ConfigWizard::SP_WELCOME)
Definition GUI_App.cpp:9965

References config_wizard_startup(), m_app_conf_exists, preset_bundle, Slic3r::GUI::ConfigWizard::RR_DATA_EMPTY, and run_wizard().

Referenced by config_wizard_startup(), and post_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ copy_network_if_available()

void Slic3r::GUI::GUI_App::copy_network_if_available ( )
private
3836{
3837 if (app_config->get("update_network_plugin") != "true")
3838 return;
3839
3840 bool had_cache = false;
3841 bool installed = install_network_plugin_from_ota(had_cache);
3842 // Success consumes the cache and a missing cache leaves nothing to do; only a
3843 // failed copy keeps the flag so the install is retried on the next launch.
3844 if (installed || !had_cache)
3845 app_config->set("update_network_plugin", "false");
3846}
bool install_network_plugin_from_ota(bool &had_cache)
Definition GUI_App.cpp:3852

References app_config, copy_network_if_available(), and install_network_plugin_from_ota().

Referenced by copy_network_if_available(), and on_init_inner().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ copy_older_config()

void Slic3r::GUI::GUI_App::copy_older_config ( )
private
2845{
2847}
std::string m_older_data_dir_path
Definition GUI_App.hpp:910

References copy_older_config(), m_older_data_dir_path, and preset_bundle.

Referenced by copy_older_config(), and on_init_inner().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ current_language_code()

wxString Slic3r::GUI::GUI_App::current_language_code ( ) const
inline
713{ return m_active_language_code.empty() && m_wxLocale ? m_wxLocale->GetCanonicalName() : m_active_language_code; }
std::unique_ptr< wxLocale > m_wxLocale
Definition GUI_App.hpp:302
wxString m_active_language_code
Definition GUI_App.hpp:307

References m_active_language_code, and m_wxLocale.

Referenced by current_language_code_safe(), open_mall_page_dialog(), open_publish_page_dialog(), and post_init().

Here is the caller graph for this function:

◆ current_language_code_safe()

wxString Slic3r::GUI::GUI_App::current_language_code_safe ( ) const
9917{
9918 // Translate the language code to a code, for which Prusa Research maintains translations.
9919 const std::map<wxString, wxString> mapping {
9920 { "cs", "cs_CZ", },
9921 { "sk", "cs_CZ", },
9922 { "de", "de_DE", },
9923 { "nl", "nl_NL", },
9924 { "sv", "sv_SE", },
9925 { "es", "es_ES", },
9926 { "fr", "fr_FR", },
9927 { "it", "it_IT", },
9928 { "ja", "ja_JP", },
9929 { "ko", "ko_KR", },
9930 { "pl", "pl_PL", },
9931 { "uk", "uk_UA", },
9932 { "zh", "zh_CN", },
9933 { "ru", "ru_RU", },
9934 { "tr", "tr_TR", },
9935 { "pt", "pt_BR", },
9936 { "lt", "lt_LT", },
9937 { "vi", "vi_VN", },
9938 { "th", "th_TH", },
9939 };
9940 wxString language_code = this->current_language_code().BeforeFirst('_');
9941 auto it = mapping.find(language_code);
9942 if (it != mapping.end())
9943 language_code = it->second;
9944 else
9945 language_code = "en_US";
9946 return language_code;
9947}
wxString current_language_code() const
Definition GUI_App.hpp:713

References current_language_code(), and current_language_code_safe().

Referenced by Slic3r::anonymous_namespace{PluginHostApp.cpp}::app_info(), current_language_code_safe(), and open_web_page_localized().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dark_mode()

bool Slic3r::GUI::GUI_App::dark_mode ( )
static
4457{
4458#ifdef SUPPORT_DARK_MODE
4459#if __APPLE__
4460 // The check for dark mode returns false positive on 10.12 and 10.13,
4461 // which allowed setting dark menu bar and dock area, which is
4462 // is detected as dark mode. We must run on at least 10.14 where the
4463 // proper dark mode was first introduced.
4464 return wxPlatformInfo::Get().CheckOSVersion(10, 14) && mac_dark_mode();
4465#else
4466 // When the user has explicitly chosen a mode, honour it directly.
4467 // Falling through to check_dark_mode() for an explicit "0" would query
4468 // wxSystemSettings::GetAppearance().IsDark(), which is contaminated by
4469 // wxWidgets 3.3's MSWEnableDarkMode(DarkMode_Auto) and can return true
4470 // even though the user asked for light mode.
4471 const auto &val = wxGetApp().app_config->get("dark_color_mode");
4472 if (val == "1") return true;
4473 if (val == "0") return false;
4474 return check_dark_mode();
4475#endif
4476#else
4477 //BBS disable DarkUI mode
4478 return false;
4479#endif
4480}
bool check_dark_mode()
Definition GUI_Utils.cpp:311
bool mac_dark_mode()
Definition MacDarkMode.mm:28

References Slic3r::GUI::check_dark_mode(), dark_mode(), and Slic3r::GUI::mac_dark_mode().

Referenced by dark_mode(), force_colors_update(), get_label_default_clr_modified(), get_label_default_clr_system(), init_label_colours(), on_init_inner(), Update_dark_mode_flag(), and UpdateDVCDarkUI().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ delete_preset_from_cloud()

void Slic3r::GUI::GUI_App::delete_preset_from_cloud ( std::string setting_id,
std::string preset_file_path )
9461{
9462 std::scoped_lock l(mutex_delete_cache_presets);
9463 fs::path info_path = fs::path(preset_file_path);
9464 info_path.replace_extension("info");
9465 need_delete_presets.emplace(setting_id, info_path.string());
9466}
std::map< std::string, std::string > need_delete_presets
Definition GUI_App.hpp:328
static std::mutex mutex_delete_cache_presets
Definition GUI_App.cpp:9427

References delete_preset_from_cloud(), Slic3r::GUI::mutex_delete_cache_presets, and need_delete_presets.

Referenced by delete_preset_from_cloud(), and scan_orphaned_info_files().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ disassociate_files()

void Slic3r::GUI::GUI_App::disassociate_files ( std::wstring extend)
10342{
10343#ifdef WIN32
10344 if (is_running_in_msix())
10345 return;
10346 wchar_t app_path[MAX_PATH];
10347 ::GetModuleFileNameW(nullptr, app_path, sizeof(app_path));
10348
10349 std::wstring prog_path = L"\"" + std::wstring(app_path) + L"\"";
10350 std::wstring prog_id = L" Orca.Slicer.1";
10351 std::wstring prog_desc = L"OrcaSlicer";
10352 std::wstring prog_command = prog_path + L" \"%1\"";
10353 std::wstring reg_base = L"Software\\Classes";
10354 std::wstring reg_extension = reg_base + L"\\." + extend;
10355 std::wstring reg_prog_id = reg_base + L"\\" + prog_id;
10356 std::wstring reg_prog_id_command = reg_prog_id + L"\\Shell\\Open\\Command";
10357
10358 bool is_new = false;
10359 is_new |= del_win_registry(HKEY_CURRENT_USER, reg_extension.c_str(), prog_id.c_str());
10360
10361 bool is_associate_3mf = app_config->get("associate_3mf") == "true";
10362 bool is_associate_stl = app_config->get("associate_stl") == "true";
10363 bool is_associate_step = app_config->get("associate_step") == "true";
10364 if (!is_associate_3mf && !is_associate_stl && !is_associate_step)
10365 {
10366 is_new |= del_win_registry(HKEY_CURRENT_USER, reg_prog_id.c_str(), prog_desc.c_str());
10367 is_new |= del_win_registry(HKEY_CURRENT_USER, reg_prog_id_command.c_str(), prog_command.c_str());
10368 }
10369
10370 if (is_new)
10371 ::SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr);
10372#endif // WIN32
10373}

References app_config, disassociate_files(), Slic3r::GUI::is_running_in_msix(), and L.

Referenced by disassociate_files().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ disassociate_url()

void Slic3r::GUI::GUI_App::disassociate_url ( std::wstring url_prefix)
10422{
10423#ifdef WIN32
10424 if (is_running_in_msix())
10425 return;
10426 wxRegKey key_full(wxRegKey::HKCU, L"Software\\Classes\\" + url_prefix + L"\\shell\\open\\command");
10427 if (!key_full.Exists()) {
10428 return;
10429 }
10430 key_full = "";
10431#endif // WIN32
10432}

References disassociate_url(), Slic3r::GUI::is_running_in_msix(), and L.

Referenced by disassociate_url().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ download_plugin()

int Slic3r::GUI::GUI_App::download_plugin ( std::string name,
std::string package_name,
InstallProgressFn pro_fn = nullptr,
WasCancelledFn cancel_fn = nullptr )
1422{
1423 int result = 0;
1424 json j;
1425 std::string err_msg;
1426
1427 // get country_code
1428 AppConfig* app_config = wxGetApp().app_config;
1429 if (!app_config) {
1430 j["result"] = "failed";
1431 j["error_msg"] = "app_config is nullptr";
1432 return -1;
1433 }
1434
1435 BOOST_LOG_TRIVIAL(info) << "[download_plugin]: enter";
1437 // get temp path
1438 fs::path target_file_path = (fs::temp_directory_path() / package_name);
1439 fs::path tmp_path = target_file_path;
1440 tmp_path += format(".%1%%2%", get_current_pid(), ".tmp");
1441
1442 // Determine OS type for plugin download (must be set per-request since global
1443 // extra headers are no longer initialised on this branch).
1444#if defined(__WINDOWS__)
1445 std::string os_type = (is_running_on_arm64() && !use_legacy_network_plugin()) ? "windows_arm" : "windows";
1446#elif defined(__APPLE__)
1447 std::string os_type = "macos";
1448#elif defined(__linux__)
1449 std::string os_type = "linux";
1450#else
1451 std::string os_type = "windows";
1452#endif
1453
1454 // get_url
1455 std::string url = get_plugin_url(name, app_config->get_country_code());
1456 std::string download_url;
1457 Slic3r::Http http_url = Slic3r::Http::get(url);
1458 BOOST_LOG_TRIVIAL(info) << "[download_plugin]: check the plugin from " << url;
1461 .header("X-BBL-OS-Type", os_type)
1462 .on_complete(
1463 [&download_url](std::string body, unsigned status) {
1464 try {
1465 json j = json::parse(body);
1466 std::string message = j["message"].get<std::string>();
1467
1468 if (message == "success") {
1469 json resource = j.at("resources");
1470 if (resource.is_array()) {
1471 for (auto iter = resource.begin(); iter != resource.end(); iter++) {
1472 Semver version;
1473 std::string version_str;
1474 std::string url;
1475 std::string type;
1476 std::string vendor;
1477 std::string description;
1478 for (auto sub_iter = iter.value().begin(); sub_iter != iter.value().end(); sub_iter++) {
1479 if (boost::iequals(sub_iter.key(), "type")) {
1480 type = sub_iter.value();
1481 BOOST_LOG_TRIVIAL(info) << "[download_plugin]: get version of settings's type, " << sub_iter.value();
1482 }
1483 else if (boost::iequals(sub_iter.key(), "version")) {
1484 version_str = sub_iter.value();
1485 version = *(Semver::parse(version_str));
1486 }
1487 else if (boost::iequals(sub_iter.key(), "description")) {
1488 description = sub_iter.value();
1489 }
1490 else if (boost::iequals(sub_iter.key(), "url")) {
1491 url = sub_iter.value();
1492 }
1493 }
1494 BOOST_LOG_TRIVIAL(info) << "[download_plugin 1]: get type " << type << ", version " << version.to_string() << ", url " << url;
1495 download_url = url;
1496 }
1497 }
1498 }
1499 else {
1500 BOOST_LOG_TRIVIAL(info) << "[download_plugin 1]: get version of plugin failed, body=" << body;
1501 }
1502 }
1503 catch (...) {
1504 BOOST_LOG_TRIVIAL(error) << "[download_plugin 1]: catch unknown exception";
1505 ;
1506 }
1507 }).on_error(
1508 [&result, &err_msg](std::string body, std::string error, unsigned int status) {
1509 BOOST_LOG_TRIVIAL(error) << "[download_plugin 1] on_error: " << error<<", body = " << body;
1510 err_msg += "[download_plugin 1] on_error: " + error + ", body = " + body;
1511 result = -1;
1512 }).perform_sync();
1513
1514 bool cancel = false;
1515 if (result < 0) {
1516 j["result"] = "failed";
1517 j["error_msg"] = err_msg;
1518 if (pro_fn) pro_fn(InstallStatusDownloadFailed, 0, cancel);
1519 return result;
1520 }
1521
1522
1523 if (download_url.empty()) {
1524 BOOST_LOG_TRIVIAL(info) << "[download_plugin 1]: no available plugin found for this app version: " << SLIC3R_VERSION;
1525 if (pro_fn) pro_fn(InstallStatusDownloadFailed, 0, cancel);
1526 j["result"] = "failed";
1527 j["error_msg"] = "[download_plugin 1]: no available plugin found for this app version: " + std::string(SLIC3R_VERSION);
1528 return -1;
1529 }
1530 else if (pro_fn) {
1531 pro_fn(InstallStatusNormal, 5, cancel);
1532 }
1533
1534 if (m_networking_cancel_update || cancel) {
1535 BOOST_LOG_TRIVIAL(info) << boost::format("[download_plugin 1]: %1%, cancelled by user") % __LINE__;
1536 j["result"] = "failed";
1537 j["error_msg"] = (boost::format("[download_plugin 1]: %1%, cancelled by user") % __LINE__).str();
1538 return -1;
1539 }
1540 BOOST_LOG_TRIVIAL(info) << "[download_plugin] get_url = " << download_url;
1541
1542 // download
1543 Slic3r::Http http = Slic3r::Http::get(download_url);
1544 int reported_percent = 0;
1545 http.header("X-BBL-OS-Type", os_type)
1546 .on_progress(
1547 [this, &pro_fn, cancel_fn, &result, &reported_percent, &err_msg](Slic3r::Http::Progress progress, bool& cancel) {
1548 int percent = 0;
1549 if (progress.dltotal != 0)
1550 percent = progress.dlnow * 50 / progress.dltotal;
1551 bool was_cancel = false;
1552 if (pro_fn && ((percent - reported_percent) >= 10)) {
1553 pro_fn(InstallStatusNormal, percent, was_cancel);
1554 reported_percent = percent;
1555 BOOST_LOG_TRIVIAL(info) << "[download_plugin 2] progress: " << reported_percent;
1556 }
1557 cancel = m_networking_cancel_update || was_cancel;
1558 if (cancel_fn)
1559 if (cancel_fn())
1560 cancel = true;
1561
1562 if (cancel) {
1563 err_msg += "[download_plugin] cancel";
1564 result = -1;
1565 }
1566 })
1567 .on_complete([&pro_fn, tmp_path, target_file_path](std::string body, unsigned status) {
1568 BOOST_LOG_TRIVIAL(info) << "[download_plugin 2] completed";
1569 bool cancel = false;
1570 int percent = 0;
1571 fs::fstream file(tmp_path, std::ios::out | std::ios::binary | std::ios::trunc);
1572 file.write(body.c_str(), body.size());
1573 file.close();
1574 fs::rename(tmp_path, target_file_path);
1575 if (pro_fn) pro_fn(InstallStatusDownloadCompleted, 80, cancel);
1576 })
1577 .on_error([&pro_fn, &result, &err_msg](std::string body, std::string error, unsigned int status) {
1578 bool cancel = false;
1579 if (pro_fn) pro_fn(InstallStatusDownloadFailed, 0, cancel);
1580 BOOST_LOG_TRIVIAL(error) << "[download_plugin 2] on_error: " << error<<", body = " << body;
1581 err_msg += "[download_plugin 2] on_error: " + error + ", body = " + body;
1582 result = -1;
1583 });
1584 http.perform_sync();
1585
1586 // No version adoption: the stored identity is the AA.BB.CC series, so install_plugin() names
1587 // the library after the configured series regardless of which build the series-keyed endpoint
1588 // served (02.08.01.53). The series config never diverges from the file name, so there is
1589 // nothing to adopt.
1590 j["result"] = result < 0 ? "failed" : "success";
1591 j["error_msg"] = err_msg;
1592 return result;
1593}
std::string get_plugin_url(std::string name, std::string country_code)
Definition GUI_App.cpp:1381
Http & on_complete(CompleteFn fn)
Definition Http.cpp:764
Http & timeout_max(long timeout)
Definition Http.cpp:569
Http & timeout_connect(long timeout)
Definition Http.cpp:562
Http & header(std::string name, const std::string &value)
Definition Http.cpp:588
@ InstallStatusDownloadCompleted
Definition UpgradeNetworkJob.hpp:21
@ InstallStatusDownloadFailed
Definition UpgradeNetworkJob.hpp:20
@ InstallStatusNormal
Definition UpgradeNetworkJob.hpp:19
unsigned get_current_pid()
Definition utils.cpp:1480
size_t dlnow
Definition Http.hpp:45
size_t dltotal
Definition Http.hpp:44

References app_config, Slic3r::Http::Progress::dlnow, Slic3r::Http::Progress::dltotal, Slic3r::GUI::format(), Slic3r::Http::get(), Slic3r::get_current_pid(), get_plugin_url(), Slic3r::Http::header(), Slic3r::http, Slic3r::GUI::InstallStatusDownloadCompleted, Slic3r::GUI::InstallStatusDownloadFailed, Slic3r::GUI::InstallStatusNormal, m_networking_cancel_update, Slic3r::Http::on_complete(), Slic3r::Semver::parse(), TIMEOUT_CONNECT, Slic3r::Http::timeout_connect(), Slic3r::Http::timeout_max(), TIMEOUT_RESPONSE, Slic3r::Semver::to_string(), and use_legacy_network_plugin().

Here is the call graph for this function:

◆ download_project()

void Slic3r::GUI::GUI_App::download_project ( std::string project_id)
5754{
5755 if (plater_) {
5756 plater_->request_download_project(project_id);
5757 }
5758}
Plater * plater_
Definition GUI_App.hpp:791

References download_project(), and plater_.

Referenced by download_project(), and request_project_download().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ downloader()

Downloader * Slic3r::GUI::GUI_App::downloader ( )
9739{
9740 return m_downloader.get();
9741}

References downloader(), and m_downloader.

Referenced by downloader().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ drain_pending_events()

void Slic3r::GUI::GUI_App::drain_pending_events ( int timeout_ms)
private
1927{
1928 const auto deadline = std::chrono::steady_clock::now() +
1929 std::chrono::milliseconds(timeout_ms);
1930 int yield_count = 0;
1931
1932 while (std::chrono::steady_clock::now() < deadline) {
1933 // Process pending events
1934 if (wxTheApp) {
1935 wxTheApp->ProcessPendingEvents();
1936 }
1937
1938 // Bounded wxYield to prevent infinite loops
1939 if (yield_count < MAX_YIELD_ITERATIONS) {
1940 wxYield();
1941 ++yield_count;
1942 }
1943
1944 std::this_thread::sleep_for(std::chrono::milliseconds(POLL_INTERVAL_MS));
1945 }
1946}

Referenced by hot_reload_network_plugin().

Here is the caller graph for this function:

◆ em_unit()

int Slic3r::GUI::GUI_App::em_unit ( ) const
inline
535{ return m_em_unit; }

References m_em_unit.

◆ enable_developer_mode()

void Slic3r::GUI::GUI_App::enable_developer_mode ( )
8790{
8791 app_config->set_bool("developer_mode", true);
8792 update_mode();
8793}
void update_mode()
Definition GUI_App.cpp:8796

References app_config, enable_developer_mode(), and update_mode().

Referenced by enable_developer_mode().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ enable_user_preset_folder()

void Slic3r::GUI::GUI_App::enable_user_preset_folder ( bool enable)
5979{
5980 if (enable) {
5981 std::string user_id = m_agent->get_user_id();
5982 app_config->set("preset_folder", user_id);
5983 GUI::wxGetApp().preset_bundle->update_user_presets_directory(user_id);
5985 } else {
5986 BOOST_LOG_TRIVIAL(info) << "preset_folder: set to empty";
5987 app_config->set("preset_folder", "");
5988 GUI::wxGetApp().preset_bundle->update_user_presets_directory(DEFAULT_USER_FOLDER_NAME);
5990 }
5991}
#define DEFAULT_USER_FOLDER_NAME
Definition PresetBundle.hpp:31
void set_cloud_user(const std::string &user_id)
Definition PluginManager.cpp:1388

References app_config, DEFAULT_USER_FOLDER_NAME, enable_user_preset_folder(), Slic3r::PluginManager::instance(), and m_agent.

Referenced by enable_user_preset_folder(), on_init_inner(), on_user_login_handle(), request_user_logout(), and restart_networking().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ enter_force_upgrade()

void Slic3r::GUI::GUI_App::enter_force_upgrade ( )
6794{
6795 wxCommandEvent *evt = new wxCommandEvent(EVT_ENTER_FORCE_UPGRADE);
6796 GUI::wxGetApp().QueueEvent(evt);
6797}

References enter_force_upgrade().

Referenced by enter_force_upgrade().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ extract_setting_id_from_info()

std::string Slic3r::GUI::GUI_App::extract_setting_id_from_info ( const std::string & info_file_path)
static
9488{
9489 boost::nowide::ifstream file(info_file_path);
9490 if (!file.is_open())
9491 return "";
9492
9493 std::string line;
9494 while (std::getline(file, line)) {
9495 if (line.find("setting_id") == 0) {
9496 size_t pos = line.find("=");
9497 if (pos != std::string::npos) {
9498 std::string setting_id = line.substr(pos + 1);
9499 // Trim whitespace
9500 setting_id.erase(0, setting_id.find_first_not_of(" \t"));
9501 setting_id.erase(setting_id.find_last_not_of(" \t\r\n") + 1);
9502 return setting_id;
9503 }
9504 }
9505 }
9506 return "";
9507}
Vec3d pos(const Pt &p)
Definition ReprojectPointsOnMesh.hpp:16

References extract_setting_id_from_info().

Referenced by extract_setting_id_from_info(), and scan_orphaned_info_files().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ extruders_cnt()

int Slic3r::GUI::GUI_App::extruders_cnt ( ) const
9887{
9888 const Preset& preset = preset_bundle->printers.get_selected_preset();
9889 return preset.printer_technology() == ptSLA ? 1 :
9890 preset.config.option<ConfigOptionFloats>("nozzle_diameter")->values.size();
9891}
size_t size() const override
Definition Config.hpp:722
@ ptSLA
Definition Config.hpp:233
@ Preset
Definition calib.hpp:39
ConfigOptionFloatsTempl< false > ConfigOptionFloats
Definition Config.hpp:1015

References Slic3r::Preset::config, extruders_cnt(), Slic3r::ConfigBase::option(), preset_bundle, Slic3r::Preset::printer_technology(), and Slic3r::ptSLA.

Referenced by extruders_cnt().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ extruders_edited_cnt()

int Slic3r::GUI::GUI_App::extruders_edited_cnt ( ) const
9895{
9896 const Preset& preset = preset_bundle->printers.get_edited_preset();
9897 return preset.printer_technology() == ptSLA ? 1 :
9898 preset.config.option<ConfigOptionFloats>("nozzle_diameter")->values.size();
9899}

References Slic3r::Preset::config, extruders_edited_cnt(), Slic3r::ConfigBase::option(), preset_bundle, Slic3r::Preset::printer_technology(), and Slic3r::ptSLA.

Referenced by extruders_edited_cnt().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ filaments_cnt()

int Slic3r::GUI::GUI_App::filaments_cnt ( ) const
9903{
9904 return preset_bundle->filament_presets.size();
9905}

References filaments_cnt(), and preset_bundle.

Referenced by filaments_cnt().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ filter_string()

wxString Slic3r::GUI::GUI_App::filter_string ( wxString str)
9561{
9562 std::string result = str.utf8_string();
9563 std::string input = str.utf8_string();
9564
9565
9566 std::regex domainRegex(R"(([a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(?:\.[a-zA-Z]{2,})?))");
9567 std::sregex_iterator it(input.begin(), input.end(), domainRegex);
9568 std::sregex_iterator end;
9569
9570 while (it != end) {
9571 std::smatch match = *it;
9572 std::string domain = match.str();
9573 result.replace(match.position(), domain.length(), "[***]");
9574 ++it;
9575 }
9576
9577 return wxString::FromUTF8(result);
9578}

References filter_string().

Referenced by filter_string().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ FilterEvent()

int Slic3r::GUI::GUI_App::FilterEvent ( wxEvent & event)
override
8747{
8748 if ((!event.IsCommandEvent() && (event.GetEventCategory() & wxEVT_CATEGORY_USER_INPUT)) ||
8749 (event.GetEventType() == wxEVT_SIZE && event.GetEventObject() == mainframe))
8750 m_last_input = std::chrono::steady_clock::now();
8751 return Event_Skip;
8752}
std::chrono::steady_clock::time_point m_last_input
Definition GUI_App.hpp:271

References FilterEvent(), m_last_input, and mainframe.

Referenced by FilterEvent().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ focus_mode()

bool Slic3r::GUI::GUI_App::focus_mode ( ) const
inline
450{ return app_config->get_bool("focus_mode"); }

References app_config.

Referenced by toggle_focus_mode().

Here is the caller graph for this function:

◆ force_colors_update()

void Slic3r::GUI::GUI_App::force_colors_update ( )
5143{
5144#ifdef _MSW_DARK_MODE
5145#ifdef __WINDOWS__
5147#if wxVERSION_NUMBER < 3300
5148 if (WXHWND wxHWND = wxToolTip::GetToolTipCtrl())
5150#endif
5152
5153
5154 //NppDarkMode::SetDarkExplorerTheme((HWND)mainframe->m_settings_dialog.GetHWND());
5155 //NppDarkMode::SetDarkTitleBar(mainframe->m_settings_dialog.GetHWND());
5156
5157#endif // __WINDOWS__
5158#endif //_MSW_DARK_MODE
5159 m_force_colors_update = true;
5160}
bool m_force_colors_update
Definition GUI_App.hpp:290
static bool dark_mode()
Definition GUI_App.cpp:4456
void SetDarkMode(bool dark_mode)
Definition dark_mode.cpp:313
void SetDarkTitleBar(HWND hwnd)
Definition dark_mode.cpp:357
void SetDarkExplorerTheme(HWND hwnd)
Definition dark_mode.cpp:367

References dark_mode(), force_colors_update(), m_force_colors_update, mainframe, NppDarkMode::SetDarkExplorerTheme(), NppDarkMode::SetDarkMode(), and NppDarkMode::SetDarkTitleBar().

Referenced by force_colors_update().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ force_menu_update()

void Slic3r::GUI::GUI_App::force_menu_update ( )

◆ force_push_conflicting_preset()

void Slic3r::GUI::GUI_App::force_push_conflicting_preset ( const std::string & setting_id)
8275{
8276 if (setting_id.empty() || !preset_bundle)
8277 return;
8278
8279 // Queue the id so the next push-sync re-uploads this preset with force=true.
8280 {
8281 std::scoped_lock lock(conflict_ids_mutex);
8282 m_pending_conflict_setting_ids.push_back(setting_id);
8283 }
8284
8285 const std::string user_id = m_agent ? m_agent->get_user_id() : std::string();
8286
8287 // The 409 left this preset on "hold", which get_user_presets() skips. Restore it to
8288 // "update" so the next push-sync re-includes it and consumes the queued force flag.
8289 // (We must NOT pull from the cloud here as the Pull path does — that would overwrite
8290 // the local changes the user is trying to force-push.)
8291 // For a -3 tombstone on a newly created preset the on-disk setting_id is EMPTY (it only
8292 // gets assigned after a successful first push), so derive it on the fly from the preset
8293 // name and stamp it onto the preset — otherwise sync_with_lock's `id == preset.setting_id`
8294 // check never fires and the force-push silently no-ops.
8295 PresetCollection* collections[] = {&preset_bundle->prints, &preset_bundle->filaments, &preset_bundle->printers};
8296 for (PresetCollection* coll : collections) {
8297 for (const Preset& preset : coll->get_presets()) {
8298 if (preset.sync_info != "hold")
8299 continue;
8300 const std::string preset_id = preset.setting_id.empty()
8302 : preset.setting_id;
8303 if (preset_id == setting_id) {
8304 coll->set_sync_info_and_save(preset.name, setting_id, "update", 0, user_id);
8305 break;
8306 }
8307 }
8308 }
8309
8310 // Nudge the sync loop to push on its next tick instead of waiting for the 60s cadence.
8311 m_sync_user_presets_now.store(true, std::memory_order_release);
8312}
std::vector< std::string > m_pending_conflict_setting_ids
Definition GUI_App.hpp:330
static std::string generate_uuid_for_setting_id(const std::string &name, const std::string &user_id="")
Definition OrcaCloudServiceAgent.cpp:537
static std::mutex conflict_ids_mutex
Definition GUI_App.cpp:5805
@ lock
Definition GLGizmoEmboss.cpp:209

References Slic3r::GUI::conflict_ids_mutex, force_push_conflicting_preset(), Slic3r::OrcaCloudServiceAgent::generate_uuid_for_setting_id(), m_agent, m_pending_conflict_setting_ids, m_sync_user_presets_now, and preset_bundle.

Referenced by force_push_conflicting_preset(), and on_http_error().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ format_display_version()

std::string Slic3r::GUI::GUI_App::format_display_version ( )
static
6934{
6935 if (!version_display.empty()) return version_display;
6936
6937 version_display = SoftFever_VERSION;
6938 return version_display;
6939}
static std::string version_display
Definition GUI_App.hpp:349

References format_display_version(), and version_display.

Referenced by format_display_version(), and Slic3r::GUI::AboutDialog::onCopyToClipboard().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ format_IP()

std::string Slic3r::GUI::GUI_App::format_IP ( const std::string & ip)
6942{
6943 std::string format_ip = ip;
6944 size_t pos_st = 0;
6945 size_t pos_en = 0;
6946
6947 for (int i = 0; i < 2; i++) {
6948 pos_en = format_ip.find('.', pos_st + 1);
6949 if (pos_en == std::string::npos) {
6950 return ip;
6951 }
6952 format_ip.replace(pos_st, pos_en - pos_st, "***");
6953 pos_st = pos_en + 1;
6954 }
6955
6956 return format_ip;
6957}

References format_IP().

Referenced by format_IP().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ from_hex()

char Slic3r::GUI::GUI_App::from_hex ( char ch)
9826 {
9827 return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
9828}

References from_hex().

Referenced by from_hex().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_app_mode()

EAppMode Slic3r::GUI::GUI_App::get_app_mode ( ) const
inline
403{ return m_app_mode; }

References m_app_mode.

◆ get_bbl_client_version()

std::string Slic3r::GUI::GUI_App::get_bbl_client_version ( )
2850{
2851 if (BBLNetworkPlugin::instance().get_get_my_token() == nullptr) {
2852 return "01.10.01.50";
2853 }
2854 return VersionInfo::convert_full_version(SLIC3R_VERSION);
2855}
static BBLNetworkPlugin & instance()
Definition BBLNetworkPlugin.cpp:56

References Slic3r::GUI::VersionInfo::convert_full_version(), get_bbl_client_version(), and Slic3r::BBLNetworkPlugin::instance().

Referenced by get_bbl_client_version().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_color_hovered_btn_label()

const wxColour & Slic3r::GUI::GUI_App::get_color_hovered_btn_label ( )
inline
wxColour m_color_hovered_btn_label
Definition GUI_App.hpp:286

References m_color_hovered_btn_label.

◆ get_color_selected_btn_bg()

const wxColour & Slic3r::GUI::GUI_App::get_color_selected_btn_bg ( )
inline
523{ return m_color_selected_btn_bg; }
wxColour m_color_selected_btn_bg
Definition GUI_App.hpp:289

References m_color_selected_btn_bg.

◆ get_colour_approx_luma()

unsigned Slic3r::GUI::GUI_App::get_colour_approx_luma ( const wxColour & colour)
static
4218{
4219 double r = colour.Red();
4220 double g = colour.Green();
4221 double b = colour.Blue();
4222
4223 return std::round(std::sqrt(
4224 r * r * .241 +
4225 g * g * .691 +
4226 b * b * .068
4227 ));
4228}

References get_colour_approx_luma().

Referenced by get_colour_approx_luma().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_current_shader()

GLShaderProgram * Slic3r::GUI::GUI_App::get_current_shader ( )
inline
835{ return m_opengl_mgr.get_current_shader(); }
OpenGLManager m_opengl_mgr
Definition GUI_App.hpp:309

References m_opengl_mgr.

◆ get_delete_cache_presets()

std::map< std::string, std::string > & Slic3r::GUI::GUI_App::get_delete_cache_presets ( )
9430{
9431 return need_delete_presets;
9432}

References get_delete_cache_presets(), and need_delete_presets.

Referenced by get_delete_cache_presets(), and reload_settings().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_delete_cache_presets_lock()

std::map< std::string, std::string > Slic3r::GUI::GUI_App::get_delete_cache_presets_lock ( )
9435{
9436 std::scoped_lock l(mutex_delete_cache_presets);
9437 return need_delete_presets;
9438}

References get_delete_cache_presets_lock(), Slic3r::GUI::mutex_delete_cache_presets, and need_delete_presets.

Referenced by get_delete_cache_presets_lock(), and process_delete_presets().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_download_model_name()

std::string Slic3r::GUI::GUI_App::get_download_model_name ( )
inline
std::string m_mall_model_download_name
Definition GUI_App.hpp:754

References m_mall_model_download_name.

◆ get_download_model_url()

std::string Slic3r::GUI::GUI_App::get_download_model_url ( )
inline
std::string m_mall_model_download_url
Definition GUI_App.hpp:753

References m_mall_model_download_url.

◆ get_filament_color_code_query()

FilamentColorCodeQuery * Slic3r::GUI::GUI_App::get_filament_color_code_query ( )
10207{
10209 {
10210 m_filament_color_code_query = new FilamentColorCodeQuery();
10211 }
10212
10214}
FilamentColorCodeQuery * m_filament_color_code_query
Definition GUI_App.hpp:351

References get_filament_color_code_query(), and m_filament_color_code_query.

Referenced by get_filament_color_code_query().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_gl_info()

std::string Slic3r::GUI::GUI_App::get_gl_info ( bool for_github)
static
2617{
2618 return OpenGLManager::get_gl_info().to_string(for_github);
2619}
std::string to_string(bool for_github) const
Definition OpenGLManager.cpp:195
static const GLInfo & get_gl_info()
Definition OpenGLManager.hpp:106

References get_gl_info(), and Slic3r::GUI::OpenGLManager::get_gl_info().

Referenced by get_gl_info().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_highlight_default_clr()

const wxColour & Slic3r::GUI::GUI_App::get_highlight_default_clr ( )
inline
wxColour m_color_highlight_default
Definition GUI_App.hpp:288

References m_color_highlight_default.

Referenced by Slic3r::GUI::anonymous_namespace{WebViewHostDialog.cpp}::host_theme_vars_css().

Here is the caller graph for this function:

◆ get_hms_query()

HMSQuery * Slic3r::GUI::GUI_App::get_hms_query ( )
inline
408{ return hms_query; }
HMSQuery * hms_query
Definition GUI_App.hpp:350

References hms_query.

◆ get_http_url()

std::string Slic3r::GUI::GUI_App::get_http_url ( std::string country_code,
std::string path = {} )
1330{
1331 std::string url;
1332 if (country_code == "US") {
1333 url = "https://api.bambulab.com/";
1334 }
1335 else if (country_code == "CN") {
1336 url = "https://api.bambulab.cn/";
1337 }
1338 else if (country_code == "ENV_CN_DEV") {
1339 url = "https://api-dev.bambu-lab.com/";
1340 }
1341 else if (country_code == "ENV_CN_QA") {
1342 url = "https://api-qa.bambu-lab.com/";
1343 }
1344 else if (country_code == "ENV_CN_PRE") {
1345 url = "https://api-pre.bambu-lab.com/";
1346 }
1347 else {
1348 url = "https://api.bambulab.com/";
1349 }
1350
1351 url += path.empty() ? "v1/iot-service/api/slicer/resource" : path;
1352 return url;
1353}

Referenced by check_new_version(), check_privacy_version(), get_plugin_url(), and post_init().

Here is the caller graph for this function:

◆ get_inf_dialog_contect()

wxString Slic3r::GUI::GUI_App::get_inf_dialog_contect ( )
inline
462{return m_info_dialog_content;};
wxString m_info_dialog_content
Definition GUI_App.hpp:375

References m_info_dialog_content.

◆ get_instance_hash_int()

size_t Slic3r::GUI::GUI_App::get_instance_hash_int ( )
inline
814{ return m_instance_hash_int; }
size_t m_instance_hash_int
Definition GUI_App.hpp:318

References m_instance_hash_int.

◆ get_instance_hash_string()

std::string Slic3r::GUI::GUI_App::get_instance_hash_string ( )
inline
813{ return m_instance_hash_string; }
std::string m_instance_hash_string
Definition GUI_App.hpp:317

References m_instance_hash_string.

◆ get_label_clr_default()

const wxColour & Slic3r::GUI::GUI_App::get_label_clr_default ( )
inline
515{ return m_color_label_default; }
wxColour m_color_label_default
Definition GUI_App.hpp:283

References m_color_label_default.

Referenced by Slic3r::GUI::anonymous_namespace{WebViewHostDialog.cpp}::host_theme_vars_css().

Here is the caller graph for this function:

◆ get_label_clr_modified()

const wxColour & Slic3r::GUI::GUI_App::get_label_clr_modified ( )
inline
513{ return m_color_label_modified; }
wxColour m_color_label_modified
Definition GUI_App.hpp:281

References m_color_label_modified.

◆ get_label_clr_sys()

const wxColour & Slic3r::GUI::GUI_App::get_label_clr_sys ( )
inline
514{ return m_color_label_sys; }
wxColour m_color_label_sys
Definition GUI_App.hpp:282

References m_color_label_sys.

Referenced by Slic3r::GUI::anonymous_namespace{WebViewHostDialog.cpp}::host_theme_vars_css().

Here is the caller graph for this function:

◆ get_label_default_clr_modified()

const wxColour Slic3r::GUI::GUI_App::get_label_default_clr_modified ( )
4488{
4489 return dark_mode() ? wxColour(253, 111, 40) : wxColour(252, 77, 1);
4490}

References dark_mode(), and get_label_default_clr_modified().

Referenced by get_label_default_clr_modified().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_label_default_clr_system()

const wxColour Slic3r::GUI::GUI_App::get_label_default_clr_system ( )
4483{
4484 return dark_mode() ? wxColour(115, 220, 103) : wxColour(26, 132, 57);
4485}

References dark_mode(), and get_label_default_clr_system().

Referenced by get_label_default_clr_system().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_label_highlight_clr()

const wxColour & Slic3r::GUI::GUI_App::get_label_highlight_clr ( )
inline
wxColour m_color_highlight_label_default
Definition GUI_App.hpp:285

References m_color_highlight_label_default.

◆ get_latest_network_version()

std::string Slic3r::GUI::GUI_App::get_latest_network_version ( ) const
2136{
2138}
const char * get_latest_network_version()
Definition bambu_networking.hpp:443

References Slic3r::get_latest_network_version().

Referenced by check_networking_version(), get_plugin_url(), has_network_update_available(), install_plugin(), on_init_network(), and show_network_plugin_download_dialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_layer_tab()

Tab * Slic3r::GUI::GUI_App::get_layer_tab ( )
8699{
8700 return model_tabs_list[2];
8701}

References get_layer_tab(), and model_tabs_list.

Referenced by get_layer_tab().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_local_models_path()

std::string Slic3r::GUI::GUI_App::get_local_models_path ( )
2876{
2877 std::string local_path = "";
2878 if (data_dir().empty()) {
2879 return local_path;
2880 }
2881
2882 auto models_folder = (boost::filesystem::path(data_dir()) / "models");
2883 local_path = models_folder.string();
2884
2885 if (!fs::exists(models_folder)) {
2886 if (!fs::create_directory(models_folder)) {
2887 local_path = "";
2888 }
2889 BOOST_LOG_TRIVIAL(info) << "create models folder:" << models_folder.string();
2890 }
2891 return local_path;
2892}
const std::string & data_dir()
Definition utils.cpp:365

References Slic3r::data_dir(), Slic3r::empty(), and get_local_models_path().

Referenced by get_local_models_path().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_login_info()

void Slic3r::GUI::GUI_App::get_login_info ( const std::string & provider = ORCA_CLOUD_PROVIDER)
5300{
5301 if (m_agent) {
5302 if (m_agent->is_user_login(provider)) {
5303 std::string login_cmd = m_agent->build_login_cmd(provider);
5304 wxString strJS = wxString::Format("window.postMessage(%s)", from_u8(login_cmd));
5305 GUI::wxGetApp().run_script(strJS);
5306 } else {
5307 m_agent->user_logout(false, provider);
5308 std::string logout_cmd = m_agent->build_logout_cmd(provider);
5309 wxString strJS = wxString::Format("window.postMessage(%s)", from_u8(logout_cmd));
5310 GUI::wxGetApp().run_script(strJS);
5311 }
5312 if (WebViewPanel* home = WebViewPanel::if_built())
5313 home->SetLoginPanelVisibility(true);
5314 }
5315}
static WebViewPanel * if_built()
Definition Lazy.hpp:183

References Slic3r::GUI::from_u8(), get_login_info(), Slic3r::GUI::LazyInstance< WebViewPanel >::if_built(), and m_agent.

Referenced by get_login_info(), handle_web_request(), and request_login().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_min_size()

wxSize Slic3r::GUI::GUI_App::get_min_size ( ) const
4862{
4863 return wxSize(76*m_em_unit, 49 * m_em_unit);
4864}

References get_min_size(), and m_em_unit.

Referenced by get_min_size().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_mode()

ConfigOptionMode Slic3r::GUI::GUI_App::get_mode ( )
8755{
8756 return app_config->get_bool("developer_mode") ? comDevelop : get_saved_mode();
8757}
ConfigOptionMode get_saved_mode()
Definition GUI_App.cpp:8726
@ comDevelop
Definition Config.hpp:225

References app_config, Slic3r::comDevelop, get_mode(), and get_saved_mode().

Referenced by get_mode(), and get_mode_str().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_mode_str()

std::string Slic3r::GUI::GUI_App::get_mode_str ( )
8765{
8767}
ConfigOptionMode get_mode()
Definition GUI_App.cpp:8754
std::string effective_mode_to_string(ConfigOptionMode mode)
Definition GUI_App.cpp:8720

References get_mode(), and get_mode_str().

Referenced by get_mode_str().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_model_http_url()

std::string Slic3r::GUI::GUI_App::get_model_http_url ( std::string country_code)
1356{
1357 std::string url;
1358 if (country_code == "US") {
1359 url = "https://makerworld.com/";
1360 }
1361 else if (country_code == "CN") {
1362 url = "https://makerworld.com/";
1363 }
1364 else if (country_code == "ENV_CN_DEV") {
1365 url = "https://makerhub-dev.bambu-lab.com/";
1366 }
1367 else if (country_code == "ENV_CN_QA") {
1368 url = "https://makerhub-qa.bambu-lab.com/";
1369 }
1370 else if (country_code == "ENV_CN_PRE") {
1371 url = "https://makerhub-pre.bambu-lab.com/";
1372 }
1373 else {
1374 url = "https://makerworld.com/";
1375 }
1376
1377 return url;
1378}

Referenced by open_mall_page_dialog(), and open_publish_page_dialog().

Here is the caller graph for this function:

◆ get_model_tab()

Tab * Slic3r::GUI::GUI_App::get_model_tab ( bool part = false)
8694{
8695 return model_tabs_list[part ? 1 : 0];
8696}

References get_model_tab(), and model_tabs_list.

Referenced by get_model_tab().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_opengl_manager()

OpenGLManager & Slic3r::GUI::GUI_App::get_opengl_manager ( )
inline
833{ return m_opengl_mgr; }

References m_opengl_mgr.

◆ get_plate_tab()

Tab * Slic3r::GUI::GUI_App::get_plate_tab ( )
8689{
8690 return plate_tab;
8691}
Tab * plate_tab
Definition GUI_App.hpp:805

References get_plate_tab(), and plate_tab.

Referenced by get_plate_tab().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_plugin_url()

std::string Slic3r::GUI::GUI_App::get_plugin_url ( std::string name,
std::string country_code )
1382{
1383 std::string url = get_http_url(country_code);
1384
1385 std::string curr_version;
1388 } else if (name == "plugins" && app_config) {
1389 std::string user_version = app_config->get_network_plugin_version();
1390 curr_version = user_version.empty() ? get_latest_network_version() : user_version;
1391 } else {
1392 curr_version = get_latest_network_version();
1393 }
1394
1395 // The cloud endpoint is series-keyed and serves the series' newest build: AA.BB.CC.00.
1396 // Build it from the series so an 8-char series string (02.08.01) works too.
1397 std::string using_version = use_legacy_network_plugin()
1398 ? curr_version.substr(0, 9) + "00"
1399 : network_plugin_series(curr_version) + ".00";
1400 if (name == "cameratools")
1401 using_version = curr_version.substr(0, 6) + "00.00";
1402 url += (boost::format("?slicer/%1%/cloud=%2%") % name % using_version).str();
1403 return url;
1404}
std::string network_plugin_series(const std::string &version)
Definition bambu_networking.hpp:454

References app_config, BAMBU_NETWORK_AGENT_VERSION_LEGACY, get_http_url(), get_latest_network_version(), Slic3r::network_plugin_series(), and use_legacy_network_plugin().

Referenced by download_plugin().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_preset_updater()

PresetUpdater * Slic3r::GUI::GUI_App::get_preset_updater ( )
inline
793{ return preset_updater; }

References preset_updater.

◆ get_printer_cloud_provider()

std::string Slic3r::GUI::GUI_App::get_printer_cloud_provider ( ) const
5326{
5327 const std::string agent_id = resolve_printer_agent_id(
5328 preset_bundle ? preset_bundle->printers.get_edited_preset().config.opt_string("printer_agent")
5329 : std::string());
5331}
static const std::string ORCA_CLOUD_PROVIDER("orca")
static const std::string BBL_CLOUD_PROVIDER("bbl")
static constexpr char BBL_PRINTER_AGENT_ID[]
Definition NetworkAgentFactory.hpp:20

References Slic3r::BBL_CLOUD_PROVIDER(), Slic3r::BBL_PRINTER_AGENT_ID, get_printer_cloud_provider(), Slic3r::ORCA_CLOUD_PROVIDER(), preset_bundle, and resolve_printer_agent_id().

Referenced by get_printer_cloud_provider(), post_init(), and request_user_logout().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_saved_mode()

ConfigOptionMode Slic3r::GUI::GUI_App::get_saved_mode ( )
8727{
8728 if (!app_config->has("user_mode"))
8729 return comSimple;
8730
8731 return saved_mode_from_string(app_config->get("user_mode"));
8732}
ConfigOptionMode saved_mode_from_string(const std::string &mode)
Definition GUI_App.cpp:8705
@ comSimple
Definition Config.hpp:222

References app_config, Slic3r::comSimple, and get_saved_mode().

Referenced by get_mode(), get_saved_mode(), get_saved_mode_str(), and save_mode().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_saved_mode_str()

std::string Slic3r::GUI::GUI_App::get_saved_mode_str ( )
8760{
8762}
std::string saved_mode_to_string(ConfigOptionMode mode)
Definition GUI_App.cpp:8713

References get_saved_mode(), and get_saved_mode_str().

Referenced by get_saved_mode_str().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_selected_presets()

std::vector< std::pair< unsigned int, std::string > > Slic3r::GUI::GUI_App::get_selected_presets ( ) const
9175{
9176 std::vector<std::pair<unsigned int, std::string>> ret;
9177 PrinterTechnology printer_technology = preset_bundle->printers.get_edited_preset().printer_technology();
9178 for (Tab* tab : tabs_list) {
9179 if (tab->supports_printer_technology(printer_technology)) {
9180 const PresetCollection* presets = tab->get_presets();
9181 ret.push_back({ static_cast<unsigned int>(presets->type()), presets->get_selected_preset_name() });
9182 }
9183 }
9184 return ret;
9185}

References Slic3r::PresetCollection::get_presets(), Slic3r::PresetCollection::get_selected_preset_name(), get_selected_presets(), preset_bundle, Slic3r::GUI::printer_technology(), tabs_list, and Slic3r::PresetCollection::type().

Referenced by get_selected_presets(), Slic3r::GUI::ProjectDirtyStateManager::reset_initial_presets(), and Slic3r::GUI::ProjectDirtyStateManager::update_from_presets().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_shader()

GLShaderProgram * Slic3r::GUI::GUI_App::get_shader ( const std::string & shader_name)
inline
834{ return m_opengl_mgr.get_shader(shader_name); }

References m_opengl_mgr.

Referenced by Slic3r::GUI::TextLinesModel::render().

Here is the caller graph for this function:

◆ get_side_menu_popup_status()

bool Slic3r::GUI::GUI_App::get_side_menu_popup_status ( )
4810{
4811 return m_side_popup_status;
4812}
bool m_side_popup_status
Definition GUI_App.hpp:364

References get_side_menu_popup_status(), and m_side_popup_status.

Referenced by get_side_menu_popup_status().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_tab()

Tab * Slic3r::GUI::GUI_App::get_tab ( Preset::Type type)
8681{
8682 for (Tab* tab: tabs_list)
8683 if (tab->type() == type)
8684 return tab->completed() ? tab : nullptr; // To avoid actions with no-completed Tab
8685 return nullptr;
8686}

References get_tab(), and tabs_list.

Referenced by check_and_keep_current_preset_changes(), get_tab(), refresh_printer_agent_dropdown(), and Slic3r::anonymous_namespace{PluginHostPresets.cpp}::require_tab().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_window_default_clr()

const wxColour & Slic3r::GUI::GUI_App::get_window_default_clr ( )
inline
516{ return m_color_window_default; }
wxColour m_color_window_default
Definition GUI_App.hpp:284

References m_color_window_default.

Referenced by Slic3r::GUI::anonymous_namespace{WebViewHostDialog.cpp}::host_theme_vars_css().

Here is the caller graph for this function:

◆ getAgent()

NetworkAgent * Slic3r::GUI::GUI_App::getAgent ( )
inline
409{ return m_agent; }

References m_agent.

Referenced by open_mall_page_dialog(), and open_publish_page_dialog().

Here is the caller graph for this function:

◆ getDeviceManager()

Slic3r::DeviceManager * Slic3r::GUI::GUI_App::getDeviceManager ( )
inline
404{ return m_device_manager; }
Slic3r::DeviceManager * m_device_manager
Definition GUI_App.hpp:324

References m_device_manager.

Referenced by is_blocking_printing(), process_network_msg(), Slic3r::anonymous_namespace{PluginHostApp.cpp}::selected_printer(), and set_live_printer_agent().

Here is the caller graph for this function:

◆ GetSingleChoiceIndex()

int Slic3r::GUI::GUI_App::GetSingleChoiceIndex ( const wxString & message,
const wxString & caption,
const wxArrayString & choices,
int initialSelection )
8446{
8447#ifdef _WIN32
8448 wxSingleChoiceDialog dialog(nullptr, message, caption, choices);
8449 dialog.SetBackgroundColour(*wxWHITE);
8450 wxGetApp().UpdateDlgDarkUI(&dialog);
8451
8452 dialog.SetSelection(initialSelection);
8453 return dialog.ShowModal() == wxID_OK ? dialog.GetSelection() : -1;
8454#else
8455 return wxGetSingleChoiceIndex(message, caption, choices, initialSelection);
8456#endif
8457}

References GetSingleChoiceIndex().

Referenced by GetSingleChoiceIndex().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getTaskManager()

Slic3r::TaskManager * Slic3r::GUI::GUI_App::getTaskManager ( )
inline
407{ return m_task_manager; }
Slic3r::TaskManager * m_task_manager
Definition GUI_App.hpp:326

References m_task_manager.

◆ global_print_sequence()

PrintSequence Slic3r::GUI::GUI_App::global_print_sequence ( ) const
9908{
9909 PrintSequence global_print_seq = PrintSequence::ByDefault;
9910 const auto &curr_preset_config = preset_bundle->prints.get_edited_preset().config;
9911 if (curr_preset_config.has("print_sequence"))
9912 global_print_seq = curr_preset_config.option<ConfigOptionEnum<PrintSequence>>("print_sequence")->value;
9913 return global_print_seq;
9914}
PrintSequence
Definition PrintConfig.hpp:310
@ ByDefault
Definition PrintConfig.hpp:313

References Slic3r::ByDefault, global_print_sequence(), and preset_bundle.

Referenced by global_print_sequence().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_http_error()

void Slic3r::GUI::GUI_App::handle_http_error ( unsigned int status,
std::string body,
const std::string & provider = "" )
5793{
5794 // tips body size must less than 1024
5795 auto evt = new wxCommandEvent(EVT_HTTP_ERROR);
5796 evt->SetInt(status);
5797 // Encode provider into the event string alongside body
5798 json evt_data;
5799 evt_data["body"] = body;
5800 evt_data["provider"] = provider;
5801 evt->SetString(wxString::FromUTF8(evt_data.dump()));
5802 wxQueueEvent(this, evt);
5803}

References handle_http_error().

Referenced by check_new_version(), handle_http_error(), post_init(), and restart_networking().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_script_message()

void Slic3r::GUI::GUI_App::handle_script_message ( std::string msg,
const std::string & provider = ORCA_CLOUD_PROVIDER )
5725{
5726 try {
5727 json j = json::parse(msg);
5728 if (j.contains("command")) {
5729 wxString cmd = j["command"];
5730 if (cmd == "user_login") {
5731 if (m_agent) {
5732 m_agent->change_user(j.dump(), provider);
5733 if (m_agent->is_user_login(provider)) {
5734 request_user_login(1, provider);
5735 }
5736 }
5737 }
5738 }
5739 }
5740 catch (...) {
5741 ;
5742 }
5743}
void request_user_login(int online_login=0, const std::string &provider=ORCA_CLOUD_PROVIDER)
Definition GUI_App.cpp:5356

References handle_script_message(), m_agent, and request_user_login().

Referenced by handle_script_message().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_web_request()

std::string Slic3r::GUI::GUI_App::handle_web_request ( std::string cmd)
5438{
5439 try {
5440 //BBS use nlohmann json format
5441 std::stringstream ss(cmd), oss;
5442 pt::ptree root, response;
5443 pt::read_json(ss, root);
5444 if (root.empty())
5445 return "";
5446
5447 boost::optional<std::string> sequence_id = root.get_optional<std::string>("sequence_id");
5448 boost::optional<std::string> command = root.get_optional<std::string>("command");
5449 if (command.has_value()) {
5450 std::string command_str = command.value();
5451 static const std::unordered_set<std::string> stealth_blocked_info_commands = {
5452 "get_login_info",
5453 "get_orca_login_info",
5454 "get_bambu_login_info",
5455 };
5456 static const std::unordered_set<std::string> stealth_blocked_login_commands = {
5457 "homepage_login_or_register",
5458 "homepage_orca_login_or_register",
5459 "homepage_bambu_login_or_register",
5460 };
5461 if (app_config->get_stealth_mode() && stealth_blocked_info_commands.count(command_str)) {
5462 CallAfter([] {
5463 if (WebViewPanel* home = WebViewPanel::if_built())
5464 home->SendCloudProvidersInfo();
5465 });
5466 return "";
5467 }
5468 if (app_config->get_stealth_mode() && stealth_blocked_login_commands.count(command_str)) {
5469 CallAfter([this, command_str] {
5470 MessageDialog dlg(mainframe,
5471 _L("You are currently in Stealth Mode. To log into the Cloud, you need to disable Stealth Mode first."),
5472 _L("Stealth Mode"),
5473 wxOK | wxCANCEL | wxCENTRE);
5474 dlg.SetButtonLabel(wxID_OK, _L("Quit Stealth Mode"));
5475 if (dlg.ShowModal() == wxID_OK) {
5476 app_config->set_bool("stealth_mode", false);
5477 app_config->save();
5478 if (WebViewPanel* home = WebViewPanel::if_built())
5479 home->SendCloudProvidersInfo();
5480 // Continue with login
5481 if (command_str == "homepage_login_or_register")
5482 this->request_login(true);
5483 else if (command_str == "homepage_orca_login_or_register")
5485 else if (command_str == "homepage_bambu_login_or_register")
5486 this->request_login(true, BBL_CLOUD_PROVIDER);
5487 }
5488 });
5489 return "";
5490 }
5491 if (command_str.compare("request_project_download") == 0) {
5492 if (root.get_child_optional("data") != boost::none) {
5493 pt::ptree data_node = root.get_child("data");
5494 boost::optional<std::string> project_id = data_node.get_optional<std::string>("project_id");
5495 if (project_id.has_value()) {
5496 this->request_project_download(project_id.value());
5497 }
5498 }
5499 }
5500 else if (command_str.compare("open_project") == 0) {
5501 if (root.get_child_optional("data") != boost::none) {
5502 pt::ptree data_node = root.get_child("data");
5503 boost::optional<std::string> project_id = data_node.get_optional<std::string>("project_id");
5504 if (project_id.has_value()) {
5505 this->request_open_project(project_id.value());
5506 }
5507 }
5508 }
5509 else if (command_str.compare("get_login_info") == 0) {
5510 CallAfter([this] {
5512 });
5513 }
5514 else if (command_str.compare("homepage_login_or_register") == 0) {
5515 CallAfter([this] {
5516 this->request_login(true);
5517 });
5518 }
5519 else if (command_str.compare("homepage_logout") == 0) {
5520 CallAfter([this] {
5521 BOOST_LOG_TRIVIAL(info) << "logout: homepage_logout";
5522 request_user_logout(ORCA_CLOUD_PROVIDER, /*user_initiated=*/true);
5523 });
5524 }
5525 else if (command_str.compare("get_orca_login_info") == 0) {
5526 CallAfter([this] { get_login_info(ORCA_CLOUD_PROVIDER); });
5527 }
5528 else if (command_str.compare("get_bambu_login_info") == 0) {
5529 CallAfter([this] { get_login_info(BBL_CLOUD_PROVIDER); });
5530 }
5531 else if (command_str.compare("homepage_bambu_login_or_register") == 0) {
5532 CallAfter([this] { request_login(true, BBL_CLOUD_PROVIDER); });
5533 }
5534 else if (command_str.compare("homepage_bambu_logout") == 0) {
5535 CallAfter([this] {
5536 BOOST_LOG_TRIVIAL(info) << "logout: homepage_bambu_logout";
5537 request_user_logout(BBL_CLOUD_PROVIDER, /*user_initiated=*/true);
5538 });
5539 }
5540 else if (command_str.compare("homepage_orca_login_or_register") == 0) {
5541 CallAfter([this] { request_login(true, ORCA_CLOUD_PROVIDER); });
5542 }
5543 else if (command_str.compare("homepage_orca_logout") == 0) {
5544 CallAfter([this] {
5545 BOOST_LOG_TRIVIAL(info) << "logout: homepage_orca_logout";
5546 request_user_logout(ORCA_CLOUD_PROVIDER, /*user_initiated=*/true);
5547 });
5548 }
5549 else if (command_str.compare("homepage_modeldepot") == 0) {
5550 CallAfter([this] { open_mall_page_dialog(); });
5551 }
5552 else if (command_str.compare("homepage_newproject") == 0) {
5553 this->request_open_project("<new>");
5554 }
5555 else if (command_str.compare("homepage_openproject") == 0) {
5556 this->request_open_project({});
5557 }
5558 else if (command_str.compare("homepage_open_cloud") == 0) {
5559 this->open_orca_cloud();
5560 }
5561 else if (command_str.compare("homepage_close_cloud") == 0) {
5562 CallAfter([]() {
5563 if (WebViewPanel* home = WebViewPanel::if_built())
5564 home->set_cloud_mode(false);
5565 });
5566 }
5567 else if (command_str.compare("get_recent_projects") == 0) {
5568 if (mainframe) {
5569 if (WebViewPanel* home = WebViewPanel::if_built()) {
5570 home->SendRecentList(INT_MAX);
5571 }
5572 }
5573 }
5574 // else if (command_str.compare("modelmall_model_advise_get") == 0) {
5575 // if (mainframe && this->app_config->get("staff_pick_switch") == "true") {
5576 // if (mainframe->m_webview) {
5577 // mainframe->m_webview->SendDesignStaffpick(has_model_mall());
5578 // }
5579 // }
5580 // }
5581 // else if (command_str.compare("modelmall_model_open") == 0) {
5582 // if (root.get_child_optional("data") != boost::none) {
5583 // pt::ptree data_node = root.get_child("data");
5584 // boost::optional<std::string> id = data_node.get_optional<std::string>("id");
5585 // if (id.has_value() && mainframe->m_webview) {
5586 // mainframe->m_webview->OpenModelDetail(id.value(), m_agent);
5587 // }
5588 // }
5589 // }
5590 else if (command_str.compare("homepage_open_recentfile") == 0) {
5591 if (root.get_child_optional("data") != boost::none) {
5592 pt::ptree data_node = root.get_child("data");
5593 boost::optional<std::string> path = data_node.get_optional<std::string>("path");
5594 if (path.has_value()) {
5595 this->request_open_project(path.value());
5596 }
5597 }
5598 }
5599 else if (command_str.compare("homepage_delete_recentfile") == 0) {
5600 if (root.get_child_optional("data") != boost::none) {
5601 pt::ptree data_node = root.get_child("data");
5602 boost::optional<std::string> path = data_node.get_optional<std::string>("path");
5603 if (path.has_value()) {
5604 this->request_remove_project(path.value());
5605 }
5606 }
5607 }
5608 else if (command_str.compare("homepage_delete_all_recentfile") == 0) {
5609 this->request_remove_project("");
5610 }
5611 else if (command_str.compare("homepage_explore_recentfile") == 0) {
5612 if (root.get_child_optional("data") != boost::none) {
5613 pt::ptree data_node = root.get_child("data");
5614 boost::optional<std::string> path = data_node.get_optional<std::string>("path");
5615 if (path.has_value())
5616 {
5617 boost::filesystem::path NowFile(path.value());
5618
5619 std::string FilePath = NowFile.make_preferred().string();
5620 desktop_open_any_folder(FilePath);
5621 }
5622 }
5623 }
5624 else if (command_str.compare("homepage_open_hotspot") == 0) {
5625 if (root.get_child_optional("data") != boost::none) {
5626 pt::ptree data_node = root.get_child("data");
5627 boost::optional<std::string> url = data_node.get_optional<std::string>("url");
5628 if (url.has_value()) {
5629 this->request_open_project(url.value());
5630 }
5631 }
5632 }
5633 else if (command_str.compare("begin_network_plugin_download") == 0) {
5634 CallAfter([] { wxGetApp().ShowDownNetPluginDlg(); });
5635 }
5636 else if (command_str.compare("get_web_shortcut") == 0) {
5637 if (root.get_child_optional("key_event") != boost::none) {
5638 pt::ptree key_event_node = root.get_child("key_event");
5639 auto keyCode = key_event_node.get<int>("key");
5640 auto ctrlKey = key_event_node.get<bool>("ctrl");
5641 auto shiftKey = key_event_node.get<bool>("shift");
5642 auto cmdKey = key_event_node.get<bool>("cmd");
5643
5644 wxKeyEvent e(wxEVT_CHAR_HOOK);
5645#ifdef __APPLE__
5646 e.SetControlDown(cmdKey);
5647 e.SetRawControlDown(ctrlKey);
5648#else
5649 e.SetControlDown(ctrlKey);
5650#endif
5651 e.SetShiftDown(shiftKey);
5652 keyCode = keyCode == 188 ? ',' : keyCode;
5653 e.m_keyCode = keyCode;
5654 e.SetEventObject(mainframe);
5655 wxPostEvent(mainframe, e);
5656 }
5657 }
5658 else if (command_str.compare("userguide_wiki_open") == 0) {
5659 if (root.get_child_optional("data") != boost::none) {
5660 pt::ptree data_node = root.get_child("data");
5661 boost::optional<std::string> path = data_node.get_optional<std::string>("url");
5662 if (path.has_value()) {
5663 wxLaunchDefaultBrowser(path.value());
5664 }
5665 }
5666 }
5667 else if (command_str.compare("homepage_open_ccabin") == 0) {
5668 if (root.get_child_optional("data") != boost::none) {
5669 pt::ptree data_node = root.get_child("data");
5670 boost::optional<std::string> path = data_node.get_optional<std::string>("file");
5671 if (path.has_value()) {
5672 std::string Fullpath = resources_dir() + "/web/homepage/model/" + path.value();
5673
5674 this->request_open_project(Fullpath);
5675 }
5676 }
5677 }
5678 else if (command_str.compare("common_openurl") == 0) {
5679 boost::optional<std::string> path = root.get_optional<std::string>("url");
5680 if (path.has_value()) {
5681 wxLaunchDefaultBrowser(path.value());
5682 }
5683 }
5684 else if (command_str.compare("homepage_makerlab_get") == 0) {
5685 //if (mainframe->m_webview) { mainframe->m_webview->SendMakerlabList(); }
5686 }
5687 else if (command_str.compare("makerworld_model_open") == 0)
5688 {
5689 if (root.get_child_optional("model") != boost::none) {
5690 pt::ptree data_node = root.get_child("model");
5691 boost::optional<std::string> path = data_node.get_optional<std::string>("url");
5692 if (path.has_value())
5693 {
5694 wxString realurl = from_u8(url_decode(path.value()));
5695 wxGetApp().request_model_download(realurl);
5696 }
5697 }
5698 }
5699 }
5700 }
5701 catch (...) {
5702 BOOST_LOG_TRIVIAL(warning) << "parse json cmd failed " << cmd;
5703 return "";
5704 }
5705 return "";
5706}
void request_remove_project(std::string project_id)
Definition GUI_App.cpp:5787
void request_login(bool show_user_info=false, const std::string &provider=ORCA_CLOUD_PROVIDER)
Definition GUI_App.cpp:5288
void request_open_project(std::string project_id)
Definition GUI_App.cpp:5767
void request_project_download(std::string project_id)
Definition GUI_App.cpp:5760
void request_user_logout(const std::string &provider=ORCA_CLOUD_PROVIDER, bool user_initiated=false)
Definition GUI_App.cpp:5373
void get_login_info(const std::string &provider=ORCA_CLOUD_PROVIDER)
Definition GUI_App.cpp:5299
void open_mall_page_dialog()
Definition GUI_App.cpp:9749
std::string url_decode(std::string value)
Definition GUI_App.cpp:9830
void open_orca_cloud(const std::string &next=std::string())
Definition GUI_App.cpp:5708
void desktop_open_any_folder(const std::string &path)
Definition GUI.cpp:626
const std::string & resources_dir()
Definition utils.cpp:296

References _L, app_config, Slic3r::BBL_CLOUD_PROVIDER(), Slic3r::GUI::desktop_open_any_folder(), Slic3r::GUI::from_u8(), get_login_info(), handle_web_request(), Slic3r::GUI::LazyInstance< WebViewPanel >::if_built(), mainframe, open_mall_page_dialog(), open_orca_cloud(), Slic3r::ORCA_CLOUD_PROVIDER(), request_login(), request_open_project(), request_project_download(), request_remove_project(), request_user_logout(), Slic3r::resources_dir(), Slic3r::GUI::MsgDialog::SetButtonLabel(), Slic3r::GUI::DPIAware< P >::ShowModal(), and url_decode().

Referenced by handle_web_request().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ has_current_preset_changes()

bool Slic3r::GUI::GUI_App::has_current_preset_changes ( ) const
9156{
9157 PrinterTechnology printer_technology = preset_bundle->printers.get_edited_preset().printer_technology();
9158 for (const Tab* const tab : tabs_list) {
9159 if (tab->supports_printer_technology(printer_technology) && tab->current_preset_is_dirty())
9160 return true;
9161 }
9162 return false;
9163}

References has_current_preset_changes(), preset_bundle, Slic3r::GUI::printer_technology(), and tabs_list.

Referenced by check_and_keep_current_preset_changes(), check_and_save_current_preset_changes(), and has_current_preset_changes().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ has_model_mall()

bool Slic3r::GUI::GUI_App::has_model_mall ( )
4536{
4537 if (auto cc = app_config->get_region(); cc == "CNH" || cc == "China" || cc == "")
4538 return false;
4539 return true;
4540}

References app_config, and has_model_mall().

Referenced by has_model_mall().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ has_network_update_available()

bool Slic3r::GUI::GUI_App::has_network_update_available ( ) const
2141{
2142 std::string current = Slic3r::NetworkAgent::get_version();
2143 std::string latest = get_latest_network_version();
2144
2145 if (current.empty() || current == "00.00.00.00")
2146 return false;
2147
2148 return current.substr(0, 8) != latest.substr(0, 8);
2149}

References get_latest_network_version(), and Slic3r::NetworkAgent::get_version().

Referenced by on_init_network().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ has_unsaved_preset_changes()

bool Slic3r::GUI::GUI_App::has_unsaved_preset_changes ( ) const
9146{
9147 PrinterTechnology printer_technology = preset_bundle->printers.get_edited_preset().printer_technology();
9148 for (const Tab* const tab : tabs_list) {
9149 if (tab->supports_printer_technology(printer_technology) && tab->saved_preset_is_dirty())
9150 return true;
9151 }
9152 return false;
9153}

References has_unsaved_preset_changes(), preset_bundle, Slic3r::GUI::printer_technology(), and tabs_list.

Referenced by has_unsaved_preset_changes(), and Slic3r::GUI::ProjectDirtyStateManager::update_from_presets().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ hot_reload_network_plugin()

bool Slic3r::GUI::GUI_App::hot_reload_network_plugin ( )
2028{
2029 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": starting hot reload";
2030
2031 wxBusyCursor busy;
2032 wxBusyInfo info(_L("Reloading network plug-in..."), mainframe);
2033 wxYield();
2034 wxWindowDisabler disabler;
2035
2036 if (mainframe) {
2037 wxString current_tab = mainframe->m_tabpanel->GetSelectedPageName();
2038 if (current_tab == TAB_ID_MONITOR) {
2039 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": navigating away from Monitor tab before unload";
2040 mainframe->m_tabpanel->SelectPageByName(TAB_ID_PREPARE);
2041 }
2042 }
2043
2044 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": stopping sync thread before unload";
2045 if (m_user_sync_token) {
2046 m_user_sync_token.reset();
2047 }
2048 if (m_sync_update_thread.joinable()) {
2049 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": waiting for sync thread to finish";
2050 m_sync_update_thread.join();
2051 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": sync thread finished";
2052 }
2053
2054 if (m_agent) {
2055 // Stop the health check first: a result it posts after the Phase 2 drain would run while
2056 // m_agent is null or replaced.
2058
2059 // Phase 1: Clear all callbacks (stops new invocations)
2060 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Phase 1 - clearing callbacks";
2061 m_agent->set_on_ssdp_msg_fn(nullptr);
2062 m_agent->set_on_printer_connected_fn(nullptr);
2063 m_agent->set_on_server_connected_fn(nullptr);
2064 m_agent->set_on_http_error_fn(nullptr);
2065 m_agent->set_on_subscribe_failure_fn(nullptr);
2066 m_agent->set_on_message_fn(nullptr);
2067 m_agent->set_on_user_message_fn(nullptr);
2068 m_agent->set_on_local_connect_fn(nullptr);
2069 m_agent->set_on_local_message_fn(nullptr);
2070 m_agent->set_queue_on_main_fn(nullptr);
2071
2072 // Phase 2: Drain pending CallAfter callbacks (bounded)
2073 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Phase 2 - draining callbacks";
2074 drain_pending_events(CALLBACK_DRAIN_TIMEOUT_MS);
2075
2076 // Phase 3: Stop operations and verify return values
2077 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Phase 3 - stopping operations";
2078 bool discovery_stopped = m_agent->start_discovery(false, false);
2079 int disconnect_result = m_agent->disconnect_printer();
2080 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": discovery_stopped=" << discovery_stopped
2081 << ", disconnect_result=" << disconnect_result;
2082
2083 // Phase 4: Wait for idle with state verification
2084 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Phase 4 - waiting for idle";
2085 bool became_idle = wait_for_network_idle(NETWORK_IDLE_TIMEOUT_MS);
2086 if (!became_idle) {
2087 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": proceeding despite timeout";
2088 }
2089
2090 // Phase 5: Final bounded drain before destruction
2091 drain_pending_events(FINAL_DRAIN_TIMEOUT_MS);
2092
2093 // Phase 6: Destroy agent
2094 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Phase 6 - destroying agent";
2095 delete m_agent;
2096 m_agent = nullptr;
2097 }
2098
2099 // Phase 7: Unload module
2101 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Phase 7 - unloading module";
2102 drain_pending_events(FINAL_DRAIN_TIMEOUT_MS);
2103 int unload_result = Slic3r::NetworkAgent::unload_network_module();
2104 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": unload_result=" << unload_result;
2105 }
2106
2107 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": calling restart_networking";
2109 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": restart_networking returned";
2110
2111 std::string loaded_version = Slic3r::NetworkAgent::get_version();
2112 bool success = m_agent != nullptr && !loaded_version.empty() && loaded_version != "00.00.00.00";
2113 bool user_logged_in = m_agent && m_agent->is_user_login();
2114 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": after restart_networking, is_user_login = " << user_logged_in
2115 << ", m_agent = " << (m_agent ? "valid" : "null")
2116 << ", version = " << loaded_version;
2117
2118 if (success && m_agent && m_device_manager && !app_config->get_stealth_mode()) {
2119 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": connecting to cloud server";
2120 m_agent->connect_server();
2121 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": re-subscribing to cloud printers";
2122 m_device_manager->add_user_subscribe();
2123 }
2124
2125 if (MonitorPanel* monitor = MonitorPanel::if_built()) {
2126 monitor->update_network_version_footer();
2127 monitor->set_default();
2128 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": reset monitor panel";
2129 }
2130
2131 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": hot reload " << (success ? "successful" : "failed");
2132 return success;
2133}
#define TAB_ID_PREPARE
Definition MainFrame.hpp:60
#define TAB_ID_MONITOR
Definition MainFrame.hpp:62
class WXDLLIMPEXP_FWD_CORE wxWindowDisabler
Definition ProgressDialog.hpp:31
void drain_pending_events(int timeout_ms)
Definition GUI_App.cpp:1926
void restart_networking()
Definition GUI_App.cpp:1860
std::shared_ptr< int > m_user_sync_token
Definition GUI_App.hpp:354
boost::thread m_sync_update_thread
Definition GUI_App.hpp:353
bool wait_for_network_idle(int timeout_ms)
Definition GUI_App.cpp:1949
static bool is_network_module_loaded()
Definition NetworkAgent.cpp:76
static int unload_network_module()
Definition NetworkAgent.cpp:74

References _L, app_config, drain_pending_events(), Slic3r::NetworkAgent::get_version(), Slic3r::GUI::LazyInstance< MonitorPanel >::if_built(), Slic3r::NetworkAgent::is_network_module_loaded(), m_agent, m_device_manager, m_sync_update_thread, m_user_sync_token, mainframe, restart_networking(), TAB_ID_MONITOR, TAB_ID_PREPARE, Slic3r::NetworkAgent::unload_network_module(), wait_for_network_idle(), and wxWindowDisabler.

Here is the call graph for this function:

◆ imgui()

ImGuiWrapper * Slic3r::GUI::GUI_App::imgui ( )
inline
816{ return m_imgui.get(); }

References m_imgui.

Referenced by on_http_error().

Here is the caller graph for this function:

◆ import_model()

void Slic3r::GUI::GUI_App::import_model ( wxWindow * parent,
wxArrayString & input_files ) const
5221{
5222 input_files.Clear();
5223 wxFileDialog dialog(parent ? parent : GetTopWindow(),
5224#ifdef __APPLE__
5225 _L("Choose one or more files (3MF/STEP/STL/SVG/OBJ/AMF/USD*/ABC/PLY):"),
5226#else
5227 _L("Choose one or more files (3MF/STEP/STL/SVG/OBJ/AMF):"),
5228#endif
5229 from_u8(app_config->get_last_dir()), "",
5230 file_wildcards(FT_MODEL), wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST);
5231
5232 if (dialog.ShowModal() == wxID_OK)
5233 dialog.GetPaths(input_files);
5234}
@ FT_MODEL
Definition GUI_App.hpp:127
wxString file_wildcards(FileType file_type, const std::string &custom_extension)
Definition GUI_App.cpp:695

References _L, app_config, Slic3r::GUI::file_wildcards(), Slic3r::GUI::from_u8(), Slic3r::GUI::FT_MODEL, and import_model().

Referenced by import_model().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ import_zip()

void Slic3r::GUI::GUI_App::import_zip ( wxWindow * parent,
wxString & input_file ) const
5237{
5238 wxFileDialog dialog(parent ? parent : GetTopWindow(),
5239 _L("Choose ZIP file") + ":",
5240 from_u8(app_config->get_last_dir()), "",
5241 file_wildcards(FT_ZIP), wxFD_OPEN | wxFD_FILE_MUST_EXIST);
5242
5243 if (dialog.ShowModal() == wxID_OK)
5244 input_file = dialog.GetPath();
5245}
@ FT_ZIP
Definition GUI_App.hpp:128

References _L, app_config, Slic3r::GUI::file_wildcards(), Slic3r::GUI::from_u8(), Slic3r::GUI::FT_ZIP, and import_zip().

Referenced by import_zip().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_app_config()

void Slic3r::GUI::GUI_App::init_app_config ( )
private
2720{
2721 // Profiles for the alpha are stored into the PrusaSlicer-alpha directory to not mix with the current release.
2722 SetAppName(SLIC3R_APP_KEY);
2723// SetAppName(SLIC3R_APP_KEY "-alpha");
2724// SetAppName(SLIC3R_APP_KEY "-beta");
2725// SetAppDisplayName(SLIC3R_APP_NAME);
2726
2727 // Set the Slic3r data directory at the Slic3r XS module.
2728 // Unix: ~/ .Slic3r
2729 // Windows : "C:\Users\username\AppData\Roaming\Slic3r" or "C:\Documents and Settings\username\Application Data\Slic3r"
2730 // Mac : "~/Library/Application Support/Slic3r"
2731
2732 if (data_dir().empty()) {
2733 // Orca: check if data_dir folder exists in application folder use it if it exists
2734 // Note:wxStandardPaths::Get().GetExecutablePath() return following paths
2735 // Unix: /usr/local/bin/exename
2736 // Windows: "C:\Programs\AppFolder\exename.exe"
2737 // Mac: /Applications/exename.app/Contents/MacOS/exename
2738 // TODO: have no idea what to do with Linux bundles
2739 auto _app_folder = boost::filesystem::path(wxStandardPaths::Get().GetExecutablePath().ToUTF8().data()).parent_path();
2740#ifdef __APPLE__
2741 // On macOS, the executable is inside the .app bundle.
2742 _app_folder = _app_folder.parent_path().parent_path().parent_path();
2743#endif
2744 boost::filesystem::path app_data_dir_path = _app_folder / "data_dir";
2745 if (boost::filesystem::exists(app_data_dir_path)) {
2746 set_data_dir(app_data_dir_path.string());
2747 }
2748 else{
2749 boost::filesystem::path data_dir_path;
2750 #ifndef __linux__
2751 std::string data_dir = wxStandardPaths::Get().GetUserDataDir().ToUTF8().data();
2752 //BBS create folder if not exists
2753 data_dir_path = boost::filesystem::path(data_dir);
2755 #else
2756 // Since version 2.3, config dir on Linux is in ${XDG_CONFIG_HOME}.
2757 // https://github.com/prusa3d/PrusaSlicer/issues/2911
2758 wxString dir;
2759 if (! wxGetEnv(wxS("XDG_CONFIG_HOME"), &dir) || dir.empty() )
2760 dir = wxFileName::GetHomeDir() + wxS("/.config");
2761 data_dir_path = boost::filesystem::path((dir + "/" + GetAppName()).ToUTF8().data());
2762 migrate_flatpak_legacy_datadir(data_dir_path);
2763 set_data_dir(data_dir_path.string());
2764 #endif
2765 if (!boost::filesystem::exists(data_dir_path)){
2766 boost::filesystem::create_directory(data_dir_path);
2767 }
2768 }
2769
2770 // Change current dirtory of application
2771
2772#ifdef _WIN32
2773 [[maybe_unused]] auto unused_result = _chdir(encode_path((Slic3r::data_dir() + "/log").c_str()).c_str());
2774#else
2775 [[maybe_unused]] auto unused_result = chdir(encode_path((Slic3r::data_dir() + "/log").c_str()).c_str());
2776#endif
2777
2778 } else {
2779 m_datadir_redefined = true;
2780 }
2781
2782 // start log here
2783 std::time_t t = std::time(0);
2784 std::tm * now_time = std::localtime(&t);
2785 std::stringstream buf;
2786 buf << std::put_time(now_time, "debug_%a_%b_%d_%H_%M_%S_");
2787 buf << get_current_pid() << ".log";
2788 std::string log_filename = buf.str();
2789#if !BBL_RELEASE_TO_PUBLIC
2790 set_log_path_and_level(log_filename, 5);
2791#else
2792 set_log_path_and_level(log_filename, 3);
2793#endif
2794
2795 BOOST_LOG_TRIVIAL(info) << boost::format("gui mode, Current OrcaSlicer Version %1% build %2%") % SoftFever_VERSION % build_commit_label;
2796
2797 //BBS: remove GCodeViewer as seperate APP logic
2798 if (!app_config)
2799 app_config = new AppConfig();
2800 //app_config = new AppConfig(is_editor() ? AppConfig::EAppMode::Editor : AppConfig::EAppMode::GCodeViewer);
2801
2802 m_config_corrupted = false;
2803 // load settings
2804 m_app_conf_exists = app_config->exists();
2805 if (m_app_conf_exists) {
2806 std::string error = app_config->load();
2807 if (!error.empty()) {
2808 // Orca: if the config file is corrupted, we will show a error dialog and create a default config file.
2809 m_config_corrupted = true;
2810
2811 }
2812 // Save orig_version here, so its empty if no app_config existed before this run.
2813 m_last_config_version = app_config->orig_version();//parse_semver_from_ini(app_config->config_path());
2814 }
2815 else {
2816#ifdef _WIN32
2817 // update associate files from registry information
2818 if (is_associate_files(L"3mf")) {
2819 app_config->set("associate_3mf", "true");
2820 }
2821 if (is_associate_files(L"stl")) {
2822 app_config->set("associate_stl", "true");
2823 }
2824 if (is_associate_files(L"step") && is_associate_files(L"stp")) {
2825 app_config->set("associate_step", "true");
2826 }
2827#endif // _WIN32
2828 }
2829 // Speed Dial opens on a bare Space from any page by default. Seed the flag so Preferences and the
2830 // MainFrame shortcut read the same value; an existing config (true or false) is left untouched.
2831 if (app_config->get("enable_speed_dial").empty())
2832 app_config->set_bool("enable_speed_dial", true);
2833 set_logging_level(Slic3r::level_string_to_boost(app_config->get("log_severity_level")));
2834
2835}
bool m_datadir_redefined
Definition GUI_App.hpp:909
boost::optional< Semver > m_last_config_version
Definition GUI_App.hpp:912
bool m_config_corrupted
Definition GUI_App.hpp:913
const char *const build_commit_label
Definition BuildCommit.cpp:7
void set_data_dir(const std::string &dir)
Definition utils.cpp:353
std::string encode_path(const char *src)
Definition utils.cpp:1382
void set_log_path_and_level(const std::string &file, unsigned int level)
Definition utils.cpp:424
void set_logging_level(unsigned int level)
Definition utils.cpp:171
unsigned int level_string_to_boost(std::string level)
Definition utils.cpp:195

References app_config, Slic3r::GUI::build_commit_label, Slic3r::data_dir(), Slic3r::empty(), Slic3r::encode_path(), Slic3r::get_current_pid(), init_app_config(), L, Slic3r::level_string_to_boost(), m_app_conf_exists, m_config_corrupted, m_datadir_redefined, m_last_config_version, Slic3r::set_data_dir(), Slic3r::set_log_path_and_level(), and Slic3r::set_logging_level().

Referenced by GUI_App(), and init_app_config().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_download_path()

void Slic3r::GUI::GUI_App::init_download_path ( )
2660{
2661 std::string down_path = app_config->get("download_path");
2662
2663 if (down_path.empty()) {
2664 std::string user_down_path = wxStandardPaths::Get().GetUserDir(wxStandardPaths::Dir_Downloads).ToUTF8().data();
2665 app_config->set("download_path", user_down_path);
2666 }
2667 else {
2668 fs::path dp(down_path);
2669 // ORCA: non-throwing probe; ec is deliberately unread, a download_path that cannot be
2670 // probed falls back to the default like a missing one instead of failing startup.
2671 boost::system::error_code ec;
2672 if (!fs::exists(dp, ec)) {
2673
2674 std::string user_down_path = wxStandardPaths::Get().GetUserDir(wxStandardPaths::Dir_Downloads).ToUTF8().data();
2675 app_config->set("download_path", user_down_path);
2676 }
2677 }
2678}

References app_config, and init_download_path().

Referenced by GUI_App(), and init_download_path().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_fonts()

void Slic3r::GUI::GUI_App::init_fonts ( )
4749{
4750 // BBS: modify font
4752 m_bold_font = Label::Body_10.Bold();
4754
4755#ifdef __WXMAC__
4756 m_small_font.SetPointSize(11);
4757 m_bold_font.SetPointSize(13);
4758#endif /*__WXMAC__*/
4759
4760 // wxSYS_OEM_FIXED_FONT and wxSYS_ANSI_FIXED_FONT use the same as
4761 // DEFAULT in wxGtk. Use the TELETYPE family as a work-around
4762 m_code_font = wxFont(wxFontInfo().Family(wxFONTFAMILY_TELETYPE));
4763 m_code_font.SetPointSize(m_small_font.GetPointSize());
4764}
static wxFont Body_10
Definition Label.hpp:56
wxFont m_small_font
Definition GUI_App.hpp:293
wxFont m_normal_font
Definition GUI_App.hpp:295

References Label::Body_10, init_fonts(), m_bold_font, m_code_font, m_normal_font, and m_small_font.

Referenced by init_fonts(), and on_init_inner().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_glcontext()

wxGLContext * Slic3r::GUI::GUI_App::init_glcontext ( wxGLCanvas & canvas)
2622{
2623 return m_opengl_mgr.init_glcontext(canvas, init_params != nullptr ? init_params->opengl_version : std::make_pair(0, 0),
2624 init_params != nullptr ? init_params->opengl_compatibility_profile : false, init_params != nullptr ? init_params->opengl_debug : false);
2625}
GUI_InitParams * init_params
Definition GUI_App.hpp:785

References init_glcontext(), init_params, and m_opengl_mgr.

Referenced by init_glcontext().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_label_colours()

void Slic3r::GUI::GUI_App::init_label_colours ( )
4493{
4494 bool is_dark_mode = dark_mode();
4495 m_color_label_modified = is_dark_mode ? wxColour("#F1754E") : wxColour("#F1754E");
4496 m_color_label_sys = is_dark_mode ? wxColour("#B2B3B5") : wxColour("#363636");
4497
4498#if defined(_WIN32) || defined(__linux__) || defined(__APPLE__)
4499 m_color_label_default = is_dark_mode ? wxColour(250, 250, 250) : m_color_label_sys; // wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
4500 m_color_highlight_label_default = is_dark_mode ? wxColour(230, 230, 230): wxSystemSettings::GetColour(/*wxSYS_COLOUR_HIGHLIGHTTEXT*/wxSYS_COLOUR_WINDOWTEXT);
4501 m_color_highlight_default = is_dark_mode ? wxColour("#36363B") : wxColour("#F1F1F1"); // ORCA row highlighting
4502 m_color_hovered_btn_label = is_dark_mode ? wxColour(255, 255, 254) : wxColour(0,0,0);
4503 m_color_default_btn_label = is_dark_mode ? wxColour(255, 255, 254): wxColour(0,0,0);
4504 m_color_selected_btn_bg = is_dark_mode ? wxColour(84, 84, 91) : wxColour(206, 206, 206);
4505#else
4506 m_color_label_default = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
4507#endif
4508 m_color_window_default = is_dark_mode ? wxColour(43, 43, 43) : wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
4509 StateColor::SetDarkMode(is_dark_mode);
4510}
wxColour m_color_default_btn_label
Definition GUI_App.hpp:287
static void SetDarkMode(bool dark)
Definition StateColor.cpp:193

References dark_mode(), init_label_colours(), m_color_default_btn_label, m_color_highlight_default, m_color_highlight_label_default, m_color_hovered_btn_label, m_color_label_default, m_color_label_modified, m_color_label_sys, m_color_selected_btn_bg, m_color_window_default, and StateColor::SetDarkMode().

Referenced by init_label_colours(), and on_init_inner().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_networking_callbacks()

void Slic3r::GUI::GUI_App::init_networking_callbacks ( )
private
2285{
2286 BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": enter, m_agent=%1%")%m_agent;
2287 if (m_agent) {
2288 //set callbacks
2289 m_agent->set_server_callback([](std::string url, int status) {
2290 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": server_callback, url=%1%, status=%2%") % url % status;
2291 //CallAfter([this]() {
2292 // if (!m_server_error_dialog) {
2293 // /*m_server_error_dialog->EndModal(wxCLOSE);
2294 // m_server_error_dialog->Destroy();
2295 // m_server_error_dialog = nullptr;*/
2296 // m_server_error_dialog = new NetworkErrorDialog(mainframe);
2297 // }
2298 //
2299 // if(plater()->get_select_machine_dialog() && plater()->get_select_machine_dialog()->IsShown()){
2300 // return;
2301 // }
2302 //
2303 // if (m_server_error_dialog->m_show_again) {
2304 // return;
2305 // }
2306 //
2307 // if (m_server_error_dialog->IsShown()) {
2308 // return;
2309 // }
2310 //
2311 // m_server_error_dialog->ShowModal();
2312 //});
2313 });
2314
2315
2316 m_agent->set_on_server_connected_fn([this](CloudEvent event, int return_code, int reason_code) {
2317 if (is_closing()) {
2318 return;
2319 }
2320 if (return_code == 5) {
2321 GUI::wxGetApp().CallAfter([this, provider = event.provider] {
2322 BOOST_LOG_TRIVIAL(info) << "logout: login expired";
2323 // Involuntary: the desktop lost its session on its own. Leave the webview's
2324 // own session alone (guide §8).
2325 this->request_user_logout(provider, /*user_initiated=*/false);
2326 MessageDialog msg_dlg(nullptr, _L("Login information expired. Please login again."), "", wxAPPLY | wxOK);
2327 if (msg_dlg.ShowModal() == wxOK) {
2328 return;
2329 }
2330 });
2331 return;
2332 }
2333 GUI::wxGetApp().CallAfter([this, provider = event.provider] {
2334 if (is_closing())
2335 return;
2336 BOOST_LOG_TRIVIAL(trace) << "static: server connected";
2337 if (provider != this->get_printer_cloud_provider()) {
2338 return;
2339 }
2340 m_agent->set_user_selected_machine(m_agent->get_user_selected_machine());
2341 if (this->is_enable_multi_machine()) {
2342 auto evt = new wxCommandEvent(EVT_UPDATE_MACHINE_LIST);
2343 wxQueueEvent(this, evt);
2344 }
2345 m_agent->set_user_selected_machine(m_agent->get_user_selected_machine());
2346 if (m_agent->is_user_login(provider)) {
2347
2348 /*disconnect lan*/
2349 DeviceManager* dev = this->getDeviceManager();
2350 if (!dev) return;
2351
2352 MachineObject *obj = dev->get_selected_machine();
2353 if (!obj) return;
2354
2355 /* resubscribe the cache dev list */
2356 if (this->is_enable_multi_machine()) {
2357
2358 if (!dev->subscribe_list_cache.empty()) {
2359 dev->subscribe_device_list(dev->subscribe_list_cache);
2360 }
2361 }
2362 }
2363 });
2364 });
2365
2366 m_agent->set_on_printer_connected_fn([this](std::string dev_id) {
2367 if (is_closing()) {
2368 return;
2369 }
2370 GUI::wxGetApp().CallAfter([this, dev_id] {
2371 if (is_closing())
2372 return;
2373 bool tunnel = boost::algorithm::starts_with(dev_id, "tunnel/");
2374 /* request_pushing */
2375 MachineObject* obj = m_device_manager->get_my_machine(tunnel ? dev_id.substr(7) : dev_id);
2376 if (obj) {
2377 obj->is_tunnel_mqtt = tunnel;
2378 obj->command_request_push_all(true);
2379 obj->command_get_version();
2380 obj->command_get_access_code();
2381 if (m_agent)
2382 m_agent->install_device_cert(obj->get_dev_id(), obj->is_lan_mode_printer());
2383
2384 obj->set_online_state(true);
2385 }
2386 });
2387 });
2388
2389 m_agent->set_get_country_code_fn([this]() {
2390 if (app_config)
2391 return app_config->get_country_code();
2392 return std::string();
2393 }
2394 );
2395
2396 m_agent->set_on_subscribe_failure_fn([this](std::string dev_id) {
2397 CallAfter([this, dev_id] {
2399 });
2400 });
2401
2402 m_agent->set_on_local_connect_fn(
2403 [this](int state, std::string dev_id, std::string msg) {
2404 if (is_closing()) {
2405 return;
2406 }
2407 CallAfter([this, state, dev_id, msg] {
2408 if (is_closing()) {
2409 return;
2410 }
2411 /* request_pushing */
2412 MachineObject* obj = m_device_manager->get_my_machine(dev_id);
2413 wxCommandEvent event(EVT_CONNECT_LAN_MODE_PRINT);
2414
2415 if (obj) {
2416
2417 if (obj->is_lan_mode_printer()) {
2418 if (state == ConnectStatus::ConnectStatusOk) {
2419 obj->command_request_push_all(true);
2420 obj->command_get_version();
2421 event.SetInt(0);
2422 event.SetString(obj->get_dev_id());
2423
2424 obj->set_online_state(true);
2425 } else if (state == ConnectStatus::ConnectStatusFailed) {
2426 // Orca: only update status if same device id
2427 if (m_device_manager->selected_machine != dev_id) return;
2428
2429 m_device_manager->set_selected_machine("");
2430 wxString text;
2431 if (msg == "5") {
2432 obj->set_access_code("");
2433 text = wxString::Format(_L("Incorrect password"));
2434 wxGetApp().show_dialog(text);
2435 } else {
2436 text = wxString::Format(_L("Connect %s failed! [SN:%s, code=%s]"), from_u8(obj->get_dev_name()), obj->get_dev_id(), msg);
2437 wxGetApp().show_dialog(text);
2438 }
2439 event.SetInt(-1);
2440
2441 obj->set_online_state(false);
2442 } else if (state == ConnectStatus::ConnectStatusLost) {
2443 m_device_manager->set_selected_machine("");
2444 event.SetInt(-1);
2445 BOOST_LOG_TRIVIAL(info) << "set_on_local_connect_fn: state = lost";
2446
2447 obj->set_online_state(false);
2448 } else {
2449 event.SetInt(-1);
2450 BOOST_LOG_TRIVIAL(info) << "set_on_local_connect_fn: state = " << state;
2451 }
2452
2453 obj->set_lan_mode_connection_state(false);
2454 }
2455 else {
2456 if (state == ConnectStatus::ConnectStatusOk) {
2457 event.SetInt(1);
2458 event.SetString(obj->get_dev_id());
2459 }
2460 else if(msg == "5") {
2461 event.SetInt(5);
2462 event.SetString(obj->get_dev_id());
2463 }
2464 else {
2465 event.SetInt(-2);
2466 event.SetString(obj->get_dev_id());
2467 }
2468 }
2469 }
2470 if (wxGetApp().plater()->get_select_machine_dialog()) {
2471 wxPostEvent(wxGetApp().plater()->get_select_machine_dialog(), event);
2472 }
2473 });
2474 }
2475 );
2476
2477 auto message_arrive_fn = [this](std::string dev_id, std::string msg) {
2478 if (is_closing()) {
2479 return;
2480 }
2481 CallAfter([this, dev_id, msg] {
2482 if (is_closing())
2483 return;
2484
2485 if (process_network_msg(dev_id, msg)) {
2486 return;
2487 }
2488
2489 const std::string provider = this->get_printer_cloud_provider();
2490 if (MachineObject* obj = this->m_device_manager->get_user_machine(dev_id, provider)) {
2491 auto sel = this->m_device_manager->get_selected_machine();
2492 if (sel && sel->get_dev_id() == dev_id) {
2493 obj->parse_json("cloud", msg);
2494 GUI::wxGetApp().sidebar().load_ams_list(obj);
2495 } else {
2496 obj->parse_json("cloud", msg, true);
2497 }
2498 }
2499
2500 if (GUI::wxGetApp().plater())
2501 GUI::wxGetApp().plater()->update_machine_sync_status();
2502 });
2503 };
2504
2505 m_agent->set_on_message_fn(message_arrive_fn);
2506
2507 auto user_message_arrive_fn = [this](std::string user_id, std::string msg) {
2508 if (is_closing()) {
2509 return;
2510 }
2511 CallAfter([this, user_id, msg] {
2512 if (is_closing())
2513 return;
2514
2515 //check user
2516 if (user_id == m_agent->get_user_id(get_printer_cloud_provider())) {
2517 this->m_user_manager->parse_json(msg);
2518 }
2519
2520 });
2521 };
2522
2523 m_agent->set_on_user_message_fn(user_message_arrive_fn);
2524
2525
2526 auto lan_message_arrive_fn = [this](std::string dev_id, std::string msg) {
2527 if (is_closing()) {
2528 return;
2529 }
2530 CallAfter([this, dev_id, msg] {
2531 if (is_closing())
2532 return;
2533
2534 if (this->process_network_msg(dev_id, msg)) {
2535 return;
2536 }
2537
2538 if (MachineObject* obj = m_device_manager->get_my_machine(dev_id)) {
2539 obj->parse_json("lan", msg);
2540 // Orca: skip it if it doesn't support subscription based filament sync
2541 if (this->m_device_manager->get_selected_machine() == obj &&
2542 m_agent->get_filament_sync_mode() == FilamentSyncMode::subscription) {
2543 GUI::wxGetApp().sidebar().load_ams_list(obj);
2544 }
2545 }
2546
2547 if (GUI::wxGetApp().plater())
2548 GUI::wxGetApp().plater()->update_machine_sync_status();
2549 });
2550 };
2551 m_agent->set_on_local_message_fn(lan_message_arrive_fn);
2552 m_agent->set_queue_on_main_fn([this](std::function<void()> callback) {
2553 CallAfter(callback);
2554 });
2555 }
2556 BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": exit, m_agent=%1%")%m_agent;
2557}
void on_start_subscribe_again(std::string dev_id)
Definition GUI_App.cpp:2857
std::string get_printer_cloud_provider() const
Definition GUI_App.cpp:5325
Plater * plater()
Definition GUI_App.cpp:9709
bool process_network_msg(std::string dev_id, std::string msg)
Definition GUI_App.cpp:6671
bool is_closing() const
Definition GUI_App.hpp:436
bool is_enable_multi_machine()
Definition GUI_App.hpp:388
Slic3r::UserManager * m_user_manager
Definition GUI_App.hpp:325
@ ConnectStatusFailed
Definition bambu_networking.hpp:177
@ ConnectStatusLost
Definition bambu_networking.hpp:178
@ ConnectStatusOk
Definition bambu_networking.hpp:176
@ subscription
Real-time push updates via subscription (e.g., MQTT).
Definition IPrinterAgent.hpp:58

References is_closing(), is_enable_multi_machine(), m_agent, and Slic3r::CloudEvent::provider.

Referenced by on_init_network(), and restart_networking().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_opengl()

bool Slic3r::GUI::GUI_App::init_opengl ( )
2628{
2629#ifdef __linux__
2630 bool status = m_opengl_mgr.init_gl();
2631 if (status)
2632 m_opengl_initialized = true;
2633 return status;
2634#else
2635 return m_opengl_mgr.init_gl();
2636#endif
2637}

References init_opengl(), and m_opengl_mgr.

Referenced by init_opengl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_plugin_gui_wiring()

void Slic3r::GUI::GUI_App::init_plugin_gui_wiring ( )
private
3018{
3019 PluginManager& plugin_mgr = PluginManager::instance();
3020
3021 auto refresh_plugins_dialog = [] {
3022 if (!wxTheApp)
3023 return;
3024
3025 GUI_App* app = &GUI::wxGetApp();
3026 if (app->is_closing())
3027 return;
3028
3029 app->CallAfter([app] {
3030 if (!app->is_closing() && app->m_plugins_dlg)
3031 app->m_plugins_dlg->update_plugin_dialog_ui();
3032 });
3033 };
3034
3035 // why: a newly loaded plugin only adds a selectable agent
3036 // refresh the dropdown and leave the live agent alone, unless it brought a printer connection
3037 // the selected preset may be waiting for: plugins load asynchronously and can register their
3038 // agent after the startup preset is applied
3039 auto refresh_printer_agent_after_load = [](bool provides_printer_connection)
3040 {
3041 if (!wxTheApp)
3042 return;
3043
3044 GUI_App* app = &GUI::wxGetApp();
3045 if (app->is_closing())
3046 return;
3047
3048 app->CallAfter([app, provides_printer_connection]
3049 {
3050 if (app->is_closing())
3051 return;
3052
3053 if (provides_printer_connection)
3054 app->switch_printer_agent_if_pending();
3055 app->refresh_printer_agent_dropdown();
3056 });
3057 };
3058
3059 // why: the unloaded plugin may have been the provider of the live agent
3060 // re-run selection, where a now-missing agent will be cleared
3061 // refresh dropdown after
3062 auto switch_printer_agent_after_unload = [](const std::string&)
3063 {
3064 if (!wxTheApp)
3065 return;
3066
3067 GUI_App* app = &GUI::wxGetApp();
3068 if (app->is_closing())
3069 return;
3070
3071 app->CallAfter([app] {
3072 if (app->is_closing())
3073 return;
3074
3075 app->switch_printer_agent();
3076 app->refresh_printer_agent_dropdown();
3077 });
3078 };
3079
3080 plugin_mgr.subscribe_on_unload_callback(PluginHostUi::close_windows_for_plugin);
3081 plugin_mgr.subscribe_on_load_callback([refresh_plugins_dialog](const std::string&) { refresh_plugins_dialog(); });
3082 plugin_mgr.subscribe_on_unload_callback([refresh_plugins_dialog](const std::string&) { refresh_plugins_dialog(); });
3083 plugin_mgr.subscribe_on_load_callback(NetworkAgentFactory::register_python_plugin);
3084 plugin_mgr.subscribe_on_unload_callback(NetworkAgentFactory::deregister_python_plugin);
3085 plugin_mgr.subscribe_on_load_callback([](const std::string& plugin_key) {
3086 if (wxTheApp == nullptr || wxGetApp().is_closing() || wxGetApp().mainframe == nullptr)
3087 return;
3088 wxGetApp().mainframe->plugin_pages().on_plugin_register(plugin_key);
3089 });
3090 plugin_mgr.subscribe_on_unload_callback([](const std::string& plugin_key) {
3091 if (wxTheApp == nullptr || wxGetApp().is_closing() || wxGetApp().mainframe == nullptr)
3092 return;
3093 wxGetApp().mainframe->plugin_pages().on_plugin_deregister(plugin_key);
3094 });
3095 plugin_mgr.subscribe_on_load_callback([refresh_printer_agent_after_load](const std::string& plugin_key) {
3096 refresh_printer_agent_after_load(!PluginManager::instance()
3097 .get_plugin_capabilities(plugin_key, PluginCapabilityType::PrinterConnection,
3098 /*only_enabled=*/true)
3099 .empty());
3100 });
3101 plugin_mgr.subscribe_on_unload_callback(switch_printer_agent_after_unload);
3102 plugin_mgr.subscribe_on_capability_load_callback(
3103 [refresh_plugins_dialog, refresh_printer_agent_after_load](const PluginCapabilityId& capability) {
3104 if (capability.type == PluginCapabilityType::PrinterConnection)
3105 NetworkAgentFactory::register_python_printer_agent(capability.plugin_key, capability.name);
3106 refresh_plugins_dialog();
3107 refresh_printer_agent_after_load(capability.type == PluginCapabilityType::PrinterConnection);
3108 // A newly loaded capability may satisfy a missing-plugin notification; re-validate the
3109 // current plate (on the UI thread) so the notification clears once its plugin is available.
3110 if (wxTheApp && !wxGetApp().is_closing())
3111 wxGetApp().CallAfter([]() {
3112 if (Plater* plater = wxGetApp().plater())
3113 plater->revalidate_current_plate_if_plugins_missing();
3114 });
3115 if (capability.type == PluginCapabilityType::Pages && wxTheApp && !wxGetApp().is_closing() && wxGetApp().mainframe)
3116 wxGetApp().mainframe->plugin_pages().on_cap_register(capability);
3117 });
3118 plugin_mgr.subscribe_on_capability_unload_callback(
3119 [refresh_plugins_dialog, switch_printer_agent_after_unload](const PluginCapabilityId& capability) {
3120 if (capability.type == PluginCapabilityType::PrinterConnection)
3121 NetworkAgentFactory::deregister_python_printer_agent(capability.plugin_key, capability.name);
3122 if (capability.type == PluginCapabilityType::Pages && wxTheApp && !wxGetApp().is_closing() && wxGetApp().mainframe)
3123 wxGetApp().mainframe->plugin_pages().on_cap_deregister(capability);
3124 refresh_plugins_dialog();
3125 switch_printer_agent_after_unload(capability.plugin_key);
3126 });
3127 plugin_mgr.subscribe_on_load_callback([](const std::string& plugin_key) {
3128 if (wxTheApp == nullptr || wxGetApp().is_closing())
3129 return;
3132 });
3133 plugin_mgr.subscribe_on_unload_callback([](const std::string& plugin_key) {
3134 if (wxTheApp == nullptr || wxGetApp().is_closing())
3135 return;
3138 });
3139 plugin_mgr.subscribe_on_capability_load_callback([](const PluginCapabilityId& capability) {
3140 if (capability.type != PluginCapabilityType::ResourceTexture)
3141 return;
3142 if (wxTheApp == nullptr || wxGetApp().is_closing())
3143 return;
3146 });
3147 plugin_mgr.subscribe_on_capability_unload_callback([](const PluginCapabilityId& capability) {
3148 if (capability.type != PluginCapabilityType::ResourceTexture)
3149 return;
3150 if (wxTheApp == nullptr || wxGetApp().is_closing())
3151 return;
3154 });
3155 // Packs already loaded before this wiring, or in tests where no callback fires.
3158}
GUI_App()
Definition GUI_App.cpp:1252
static void deregister_python_printer_agent(const std::string &plugin_key, const std::string &capability_name)
Definition NetworkAgentFactory.cpp:451
static void deregister_python_plugin(const std::string &plugin_key)
Definition NetworkAgentFactory.cpp:425
static void register_python_printer_agent(const std::string &plugin_key, const std::string &capability_name)
Definition NetworkAgentFactory.cpp:251
static void register_python_plugin(const std::string &plugin_key)
Definition NetworkAgentFactory.cpp:244
static void close_windows_for_plugin(const std::string &plugin_key)
Definition PluginHostUi.cpp:807
void on_plugin_deregister(const std::string &plugin_key)
Definition PluginResourceTextures.cpp:63
static PluginResourceTextures & instance()
Definition PluginResourceTextures.cpp:18
void initial_sweep()
Definition PluginResourceTextures.cpp:89
void on_cap_deregister(const PluginCapabilityId &id)
Definition PluginResourceTextures.cpp:83
void on_cap_register(const PluginCapabilityId &id)
Definition PluginResourceTextures.cpp:74
void on_plugin_register(const std::string &plugin_key)
Definition PluginResourceTextures.cpp:55
void bump_texture_library_generation()
Definition TextureLibrary.cpp:356
@ Plater
Definition Shortcuts.hpp:21
@ Pages
Definition PythonPluginInterface.hpp:17
@ ResourceTexture
Definition PythonPluginInterface.hpp:17
@ PrinterConnection
Definition PythonPluginInterface.hpp:17

References GUI_App(), Slic3r::GUI::bump_texture_library_generation(), Slic3r::PluginHostUi::close_windows_for_plugin(), Slic3r::NetworkAgentFactory::deregister_python_plugin(), Slic3r::NetworkAgentFactory::deregister_python_printer_agent(), Slic3r::empty(), init_plugin_gui_wiring(), Slic3r::PluginManager::instance(), Slic3r::PluginResourceTextures::instance(), is_closing(), m_plugins_dlg, mainframe, Slic3r::PluginCapabilityId::name, Slic3r::Pages, plater(), Slic3r::PluginCapabilityId::plugin_key, Slic3r::PrinterConnection, refresh_printer_agent_dropdown(), Slic3r::NetworkAgentFactory::register_python_plugin(), Slic3r::NetworkAgentFactory::register_python_printer_agent(), Slic3r::ResourceTexture, Slic3r::PluginManager::subscribe_on_capability_load_callback(), Slic3r::PluginManager::subscribe_on_capability_unload_callback(), Slic3r::PluginManager::subscribe_on_load_callback(), Slic3r::PluginManager::subscribe_on_unload_callback(), switch_printer_agent(), switch_printer_agent_if_pending(), Slic3r::PluginCapabilityId::type, and Slic3r::GUI::PluginsDialog::update_plugin_dialog_ui().

Referenced by init_plugin_gui_wiring(), and on_init_inner().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_single_instance_checker()

void Slic3r::GUI::GUI_App::init_single_instance_checker ( const std::string & name,
const std::string & path )
2895{
2896 BOOST_LOG_TRIVIAL(debug) << "init wx instance checker " << name << " "<< path;
2897 m_single_instance_checker = std::make_unique<wxSingleInstanceChecker>(boost::nowide::widen(name), boost::nowide::widen(path));
2898}
std::unique_ptr< wxSingleInstanceChecker > m_single_instance_checker
Definition GUI_App.hpp:316

References init_single_instance_checker(), and m_single_instance_checker.

Referenced by init_single_instance_checker().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ initialized()

bool Slic3r::GUI::GUI_App::initialized ( ) const
inline
387{ return m_initialized; }
bool m_initialized
Definition GUI_App.hpp:266

References m_initialized.

Referenced by post_init().

Here is the caller graph for this function:

◆ input_idle_ms()

int Slic3r::GUI::GUI_App::input_idle_ms ( ) const
8740{
8741 return int(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - m_last_input).count());
8742}
static unsigned int count
Definition AuxiliaryDataViewModel.cpp:246

References count, input_idle_ms(), and m_last_input.

Referenced by input_idle_ms().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ install_local_plugin()

void Slic3r::GUI::GUI_App::install_local_plugin ( )
8982{
8983 if (mainframe == nullptr)
8984 return;
8985
8986 wxFileDialog dialog(mainframe, _L("Select plugin package"), wxEmptyString, wxEmptyString, _L("Plugin files (*.py;*.whl)|*.py;*.whl"),
8987 wxFD_OPEN | wxFD_FILE_MUST_EXIST);
8988 if (dialog.ShowModal() != wxID_OK)
8989 return;
8990
8991 wxString message;
8992 const bool ok = install_local_plugin_package(boost::filesystem::path(dialog.GetPath().ToUTF8().data()), mainframe, message);
8993 if (message.IsEmpty())
8994 return; // user cancelled the overwrite prompt
8995
8996 Plater* plater = this->plater();
8997 if (plater == nullptr)
8998 return;
8999 plater->get_notification_manager()->push_notification(
9002 into_u8(message));
9003}
@ ErrorNotificationLevel
Definition NotificationManager.hpp:228
bool install_local_plugin_package(const boost::filesystem::path &package_file, wxWindow *parent, wxString &message)
Definition PluginsDialog.cpp:486

References _L, Slic3r::GUI::CustomNotification, Slic3r::GUI::NotificationManager::ErrorNotificationLevel, install_local_plugin(), Slic3r::GUI::install_local_plugin_package(), Slic3r::GUI::into_u8(), mainframe, plater(), and Slic3r::GUI::NotificationManager::RegularNotificationLevel.

Referenced by install_local_plugin().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ install_network_plugin_from_ota()

bool Slic3r::GUI::GUI_App::install_network_plugin_from_ota ( bool & had_cache)
3853{
3854 had_cache = false;
3855
3856 std::string data_dir_str = data_dir();
3857 boost::filesystem::path data_dir_path(data_dir_str);
3858 auto plugin_folder = data_dir_path / "plugins";
3859 auto cache_folder = data_dir_path / "ota" / "plugins";
3860 std::string changelog_file = cache_folder.string() + "/network_plugins.json";
3861
3862 std::string cached_version;
3863 if (boost::filesystem::exists(changelog_file)) {
3864 try {
3865 boost::nowide::ifstream ifs(changelog_file);
3866 json j;
3867 ifs >> j;
3868 if (j.contains("version"))
3869 cached_version = j["version"];
3870 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": cached_version = " << cached_version;
3871 } catch (nlohmann::detail::parse_error& err) {
3872 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": parse " << changelog_file << " failed: " << err.what();
3873 }
3874 }
3875
3876 if (cached_version.empty()) {
3877 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": no version found in changelog, nothing to install";
3878 return false;
3879 }
3880 had_cache = true;
3881
3882 std::string network_library, player_library, live555_library, network_library_dst, player_library_dst, live555_library_dst;
3883#if defined(_MSC_VER) || defined(_WIN32)
3884 network_library = cache_folder.string() + "/bambu_networking.dll";
3885 player_library = cache_folder.string() + "/BambuSource.dll";
3886 live555_library = cache_folder.string() + "/live555.dll";
3887 network_library_dst = plugin_folder.string() + "/" + std::string(BAMBU_NETWORK_LIBRARY) + "_" + cached_version + ".dll";
3888 player_library_dst = plugin_folder.string() + "/BambuSource.dll";
3889 live555_library_dst = plugin_folder.string() + "/live555.dll";
3890#elif defined(__WXMAC__)
3891 network_library = cache_folder.string() + "/libbambu_networking.dylib";
3892 player_library = cache_folder.string() + "/libBambuSource.dylib";
3893 live555_library = cache_folder.string() + "/liblive555.dylib";
3894 network_library_dst = plugin_folder.string() + "/lib" + std::string(BAMBU_NETWORK_LIBRARY) + "_" + cached_version + ".dylib";
3895 player_library_dst = plugin_folder.string() + "/libBambuSource.dylib";
3896 live555_library_dst = plugin_folder.string() + "/liblive555.dylib";
3897#else
3898 network_library = cache_folder.string() + "/libbambu_networking.so";
3899 player_library = cache_folder.string() + "/libBambuSource.so";
3900 live555_library = cache_folder.string() + "/liblive555.so";
3901 network_library_dst = plugin_folder.string() + "/lib" + std::string(BAMBU_NETWORK_LIBRARY) + "_" + cached_version + ".so";
3902 player_library_dst = plugin_folder.string() + "/libBambuSource.so";
3903 live555_library_dst = plugin_folder.string() + "/liblive555.so";
3904#endif
3905
3906 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": checking network_library " << network_library << ", player_library " << player_library;
3907 if (!boost::filesystem::exists(plugin_folder)) {
3908 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": create directory " << plugin_folder.string();
3909 boost::filesystem::create_directory(plugin_folder);
3910 }
3911
3912 // Replace a destination even while the running process still maps it: an in-use
3913 // file cannot be deleted or overwritten on Windows, but it can be renamed aside;
3914 // the stale ".old" copy is swept on the next launch (see on_init_network).
3915 auto install_file = [](const std::string& src, const std::string& dst) -> bool {
3916 boost::system::error_code ec;
3917 if (boost::filesystem::exists(dst, ec)) {
3918 boost::filesystem::remove(dst, ec);
3919 if (ec) {
3920 boost::filesystem::path aside(dst);
3921 aside += ".old";
3922 boost::system::error_code ec2;
3923 boost::filesystem::remove(aside, ec2);
3924 boost::filesystem::rename(dst, aside, ec2);
3925 if (ec2) {
3926 BOOST_LOG_TRIVIAL(error) << "install_network_plugin_from_ota: cannot replace in-use file " << dst << ": " << ec2.message();
3927 return false;
3928 }
3929 }
3930 }
3931 std::string error_message;
3932 CopyFileResult cfr = copy_file(src, dst, error_message, false);
3933 if (cfr != CopyFileResult::SUCCESS) {
3934 BOOST_LOG_TRIVIAL(error) << "install_network_plugin_from_ota: copying " << src << " failed(" << cfr << "): " << error_message;
3935 return false;
3936 }
3937 static constexpr const auto perms = fs::owner_read | fs::owner_write | fs::group_read | fs::others_read;
3938 fs::permissions(dst, perms);
3939 boost::filesystem::remove(src, ec);
3940 return true;
3941 };
3942
3943 if (boost::filesystem::exists(network_library)) {
3944 if (!install_file(network_library, network_library_dst))
3945 return false;
3946 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Copying network library from " << network_library << " to " << network_library_dst << " successfully.";
3947
3948 app_config->set_network_plugin_version(cached_version);
3949 app_config->save();
3950 }
3951
3952 if (boost::filesystem::exists(player_library)) {
3953 if (!install_file(player_library, player_library_dst))
3954 return false;
3955 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Copying player library from " << player_library << " to " << player_library_dst << " successfully.";
3956 }
3957
3958 if (boost::filesystem::exists(live555_library)) {
3959 if (!install_file(live555_library, live555_library_dst))
3960 return false;
3961 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Copying live555 library from " << live555_library << " to " << live555_library_dst << " successfully.";
3962 }
3963 // All cached files consumed - drop the whole ota/plugins cache folder.
3964 try {
3965 if (boost::filesystem::exists(cache_folder))
3966 fs::remove_all(cache_folder);
3967 } catch (...) {
3968 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": failed to remove the plugin cache folder " << cache_folder.string();
3969 }
3970 return true;
3971}
#define BAMBU_NETWORK_LIBRARY
Definition bambu_networking.hpp:100
CopyFileResult copy_file(const std::string &from, const std::string &to, std::string &error_message, const bool with_check)
Definition utils.cpp:1071
CopyFileResult
Definition Utils.hpp:259
@ SUCCESS
Definition Utils.hpp:260

References app_config, BAMBU_NETWORK_LIBRARY, Slic3r::copy_file(), Slic3r::data_dir(), install_network_plugin_from_ota(), and Slic3r::SUCCESS.

Referenced by copy_network_if_available(), and install_network_plugin_from_ota().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ install_plugin()

int Slic3r::GUI::GUI_App::install_plugin ( std::string name,
std::string package_name,
InstallProgressFn pro_fn = nullptr,
WasCancelledFn cancel_fn = nullptr )
1596{
1597 bool cancel = false;
1598 std::string target_file_path = (fs::temp_directory_path() / package_name).string();
1599
1600 BOOST_LOG_TRIVIAL(info) << "[install_plugin] enter";
1601 // get plugin folder
1602 std::string data_dir_str = data_dir();
1603 boost::filesystem::path data_dir_path(data_dir_str);
1604 auto plugin_folder = data_dir_path / name;
1605 //auto plugin_folder = boost::filesystem::path(wxStandardPaths::Get().GetUserDataDir().ToUTF8().data()) / "plugins";
1606 auto backup_folder = plugin_folder/"backup";
1607 if (!boost::filesystem::exists(plugin_folder)) {
1608 BOOST_LOG_TRIVIAL(info) << "[install_plugin] will create directory "<<plugin_folder.string();
1609 boost::filesystem::create_directory(plugin_folder);
1610 }
1611 if (!boost::filesystem::exists(backup_folder)) {
1612 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", will create directory %1%")%backup_folder.string();
1613 boost::filesystem::create_directory(backup_folder);
1614 }
1615
1617 BOOST_LOG_TRIVIAL(info) << boost::format("[install_plugin]: %1%, cancelled by user")%__LINE__;
1618 return -1;
1619 }
1620 if (pro_fn) {
1621 pro_fn(InstallStatusNormal, 50, cancel);
1622 }
1623 // unzip
1624 mz_zip_archive archive;
1625 mz_zip_zero_struct(&archive);
1626 if (!open_zip_reader(&archive, target_file_path)) {
1627 BOOST_LOG_TRIVIAL(error) << boost::format("[install_plugin]: %1%, open zip file failed")%__LINE__;
1628 if (pro_fn) pro_fn(InstallStatusDownloadFailed, 0, cancel);
1630 }
1631
1632 boost::filesystem::path legacy_lib_path, legacy_lib_backup;
1633 bool had_existing_legacy = false;
1634 if (name == "plugins") {
1635#if defined(_MSC_VER) || defined(_WIN32)
1636 legacy_lib_path = plugin_folder / (std::string(BAMBU_NETWORK_LIBRARY) + ".dll");
1637#elif defined(__WXMAC__)
1638 legacy_lib_path = plugin_folder / (std::string("lib") + std::string(BAMBU_NETWORK_LIBRARY) + ".dylib");
1639#else
1640 legacy_lib_path = plugin_folder / (std::string("lib") + std::string(BAMBU_NETWORK_LIBRARY) + ".so");
1641#endif
1642 legacy_lib_backup = legacy_lib_path;
1643 legacy_lib_backup += ".backup";
1644
1645 if (boost::filesystem::exists(legacy_lib_path)) {
1646 had_existing_legacy = true;
1647 boost::system::error_code ec;
1648 boost::filesystem::rename(legacy_lib_path, legacy_lib_backup, ec);
1649 if (ec) {
1650 BOOST_LOG_TRIVIAL(warning) << "[install_plugin] failed to backup existing legacy library: " << ec.message();
1651 had_existing_legacy = false;
1652 } else {
1653 BOOST_LOG_TRIVIAL(info) << "[install_plugin] backed up existing legacy library";
1654 }
1655 }
1656 }
1657
1658 mz_uint num_entries = mz_zip_reader_get_num_files(&archive);
1659 mz_zip_archive_file_stat stat;
1660 BOOST_LOG_TRIVIAL(error) << boost::format("[install_plugin]: %1%, got %2% files")%__LINE__ %num_entries;
1661 for (mz_uint i = 0; i < num_entries; i++) {
1662 if (m_networking_cancel_update || cancel) {
1663 BOOST_LOG_TRIVIAL(info) << boost::format("[install_plugin]: %1%, cancelled by user")%__LINE__;
1664 return -1;
1665 }
1666 if (mz_zip_reader_file_stat(&archive, i, &stat)) {
1667 if (stat.m_uncomp_size > 0) {
1668 std::string dest_file;
1669 if (stat.m_is_utf8) {
1670 dest_file = stat.m_filename;
1671 }
1672 else {
1673 std::string extra(1024, 0);
1674 size_t n = mz_zip_reader_get_extra(&archive, stat.m_file_index, extra.data(), extra.size());
1675 dest_file = decode(extra.substr(0, n), stat.m_filename);
1676 }
1677 if (!is_path_within_root(dest_file, plugin_folder)) {
1678 BOOST_LOG_TRIVIAL(error) << "[install_plugin] entry " << dest_file << " resolves outside " << plugin_folder.string();
1679 close_zip_reader(&archive);
1680 if (pro_fn) { pro_fn(InstallStatusUnzipFailed, 0, cancel); }
1682 }
1683 auto dest_path = plugin_folder / dest_file;
1684 std::string dest_zip_file = encode_path(dest_path.string().c_str());
1685#ifndef WIN32
1686 // Validate a symlink's target before anything at the destination is replaced.
1687 const bool is_link = S_ISLNK(stat.m_external_attr >> 16);
1688 std::string link;
1689 if (is_link) {
1690 link.assign(stat.m_uncomp_size, 0);
1691 if (!mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, link.data(), stat.m_uncomp_size, 0) ||
1692 !is_symlink_target_within_root(dest_file, link, plugin_folder)) {
1693 BOOST_LOG_TRIVIAL(error) << "[install_plugin] link " << dest_file << " -> " << link << " is unreadable or resolves outside " << plugin_folder.string();
1694 close_zip_reader(&archive);
1695 if (pro_fn) { pro_fn(InstallStatusUnzipFailed, 0, cancel); }
1697 }
1698 }
1699#endif
1700 try {
1701 boost::filesystem::create_directories(dest_path.parent_path());
1702 // symlink_status so that an existing symlink, dangling or not, is replaced rather than written through.
1703 if (fs::exists(fs::symlink_status(dest_path))) {
1704 boost::system::error_code ec;
1705 fs::remove(dest_path, ec);
1706 if (ec) {
1707 // On Windows a currently-loaded DLL (e.g. BambuSource.dll, or the
1708 // networking library in legacy mode) cannot be deleted or overwritten
1709 // in place, which failed the whole install with "The plug-in file may
1710 // be in use" (issue #14373). It CAN however be renamed aside: the
1711 // running module keeps mapping the renamed file while we write the new
1712 // one. The stale ".old" copy is cleared on the next install/launch.
1713 boost::filesystem::path aside = dest_path;
1714 aside += ".old";
1715 boost::system::error_code ec2;
1716 fs::remove(aside, ec2);
1717 fs::rename(dest_path, aside, ec2);
1718 if (ec2) {
1719 close_zip_reader(&archive);
1720 BOOST_LOG_TRIVIAL(error) << "[install_plugin] cannot replace in-use file "
1721 << dest_path.string() << ": " << ec2.message();
1722 if (pro_fn) { pro_fn(InstallStatusUnzipFailed, 0, cancel); }
1724 }
1725 BOOST_LOG_TRIVIAL(warning) << "[install_plugin] " << dest_path.filename().string()
1726 << " was in use, renamed aside to .old";
1727 }
1728 }
1729 mz_bool res = 0;
1730#ifndef WIN32
1731 if (is_link) {
1732 res = 1;
1733 try {
1734 boost::filesystem::create_symlink(link, dest_path);
1735 } catch (const std::exception &e) {
1736 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " create_symlink:" << e.what();
1737 }
1738 } else {
1739#endif
1740 res = mz_zip_reader_extract_to_file(&archive, stat.m_file_index, dest_zip_file.c_str(), 0);
1741#ifndef WIN32
1742 }
1743#endif
1744 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", extract %1% from plugin zip %2%\n") % dest_file % stat.m_filename;
1745 if (res == 0) {
1746#ifdef WIN32
1747 std::wstring new_dest_zip_file = boost::locale::conv::utf_to_utf<wchar_t>(dest_path.generic_string());
1748 res = mz_zip_reader_extract_to_file_w(&archive, stat.m_file_index, new_dest_zip_file.c_str(), 0);
1749#endif
1750 if (res == 0) {
1751 mz_zip_error zip_error = mz_zip_get_last_error(&archive);
1752 BOOST_LOG_TRIVIAL(error) << "[install_plugin]Archive read error:" << mz_zip_get_error_string(zip_error) << std::endl;
1753 close_zip_reader(&archive);
1754 if (pro_fn) { pro_fn(InstallStatusUnzipFailed, 0, cancel); }
1756 }
1757 }
1758 }
1759 catch (const std::exception& e)
1760 {
1761 // ensure the zip archive is closed and rethrow the exception
1762 close_zip_reader(&archive);
1763 BOOST_LOG_TRIVIAL(error) << "[install_plugin]Archive read exception:"<<e.what();
1764 if (pro_fn) {
1765 pro_fn(InstallStatusUnzipFailed, 0, cancel);
1766 }
1768 }
1769 }
1770 }
1771 else {
1772 BOOST_LOG_TRIVIAL(error) << boost::format("[install_plugin]: %1%, mz_zip_reader_file_stat for file %2% failed")%__LINE__%i;
1773 }
1774 }
1775
1776 close_zip_reader(&archive);
1777
1778 if (name == "plugins") {
1779 std::string config_version = app_config->get_network_plugin_version();
1780 if (config_version.empty()) {
1781 config_version = get_latest_network_version();
1782 BOOST_LOG_TRIVIAL(info) << "[install_plugin] config_version was empty, using latest: " << config_version;
1783 app_config->set_network_plugin_version(config_version);
1784 GUI::wxGetApp().CallAfter([this] {
1785 if (app_config)
1786 app_config->save();
1787 });
1788 }
1789 if (!config_version.empty() && boost::filesystem::exists(legacy_lib_path)) {
1790#if defined(_MSC_VER) || defined(_WIN32)
1791 auto versioned_lib = plugin_folder / (std::string(BAMBU_NETWORK_LIBRARY) + "_" + config_version + ".dll");
1792#elif defined(__WXMAC__)
1793 auto versioned_lib = plugin_folder / (std::string("lib") + std::string(BAMBU_NETWORK_LIBRARY) + "_" + config_version + ".dylib");
1794#else
1795 auto versioned_lib = plugin_folder / (std::string("lib") + std::string(BAMBU_NETWORK_LIBRARY) + "_" + config_version + ".so");
1796#endif
1797 BOOST_LOG_TRIVIAL(info) << "[install_plugin] renaming newly extracted " << legacy_lib_path.string() << " to " << versioned_lib.string();
1798 boost::system::error_code ec;
1799 if (boost::filesystem::exists(versioned_lib)) {
1800 boost::filesystem::remove(versioned_lib, ec);
1801 }
1802 boost::filesystem::rename(legacy_lib_path, versioned_lib, ec);
1803 if (ec) {
1804 BOOST_LOG_TRIVIAL(error) << "[install_plugin] failed to rename to versioned: " << ec.message();
1805 }
1806 }
1807
1808 if (had_existing_legacy && boost::filesystem::exists(legacy_lib_backup)) {
1809 BOOST_LOG_TRIVIAL(info) << "[install_plugin] restoring backed up legacy library";
1810 boost::system::error_code ec;
1811 boost::filesystem::rename(legacy_lib_backup, legacy_lib_path, ec);
1812 if (ec) {
1813 BOOST_LOG_TRIVIAL(warning) << "[install_plugin] failed to restore legacy library backup: " << ec.message();
1814 }
1815 }
1816 }
1817
1818 {
1819 fs::path dir_path(plugin_folder);
1820 if (fs::exists(dir_path) && fs::is_directory(dir_path)) {
1821 int file_count = 0, file_index = 0;
1822 for (fs::directory_iterator it(dir_path); it != fs::directory_iterator(); ++it) {
1823 if (fs::is_regular_file(it->status())) { ++file_count; }
1824 }
1825 for (fs::directory_iterator it(dir_path); it != fs::directory_iterator(); ++it) {
1826 BOOST_LOG_TRIVIAL(info) << " current path:" << it->path().string();
1827 if (it->path().string() == backup_folder) {
1828 continue;
1829 }
1830 auto dest_path = backup_folder.string() + "/" + it->path().filename().string();
1831 if (fs::is_regular_file(it->status())) {
1832 BOOST_LOG_TRIVIAL(info) << " copy file:" << it->path().string() << "," << it->path().filename();
1833 try {
1834 if (pro_fn) { pro_fn(InstallStatusNormal, 50 + file_index / file_count, cancel); }
1835 file_index++;
1836 if (fs::exists(dest_path)) { fs::remove(dest_path); }
1837 std::string error_message;
1838 CopyFileResult cfr = copy_file(it->path().string(), dest_path, error_message, false);
1839 if (cfr != CopyFileResult::SUCCESS) { BOOST_LOG_TRIVIAL(error) << "Copying to backup failed(" << cfr << "): " << error_message; }
1840 } catch (const std::exception &e) {
1841 BOOST_LOG_TRIVIAL(error) << "Copying to backup failed: " << e.what();
1842 }
1843 } else {
1844 BOOST_LOG_TRIVIAL(info) << " copy framework:" << it->path().string() << "," << it->path().filename();
1845 copy_framework(it->path().string(), dest_path);
1846 }
1847 }
1848 }
1849 }
1850
1851
1852 if (pro_fn)
1853 pro_fn(InstallStatusInstallCompleted, 100, cancel);
1854 if (name == "plugins")
1855 app_config->set_bool("installed_networking", true);
1856 BOOST_LOG_TRIVIAL(info) << "[install_plugin] success";
1857 return 0;
1858}
static std::string decode(std::string const &extra, std::string const &path={})
Definition GUI_App.cpp:1406
@ InstallStatusInstallCompleted
Definition UpgradeNetworkJob.hpp:23
@ InstallStatusUnzipFailed
Definition UpgradeNetworkJob.hpp:22
bool is_symlink_target_within_root(const std::string &link_rel_path, const std::string &target, const boost::filesystem::path &root)
Definition utils.cpp:1249
bool is_path_within_root(const std::string &rel_path, const boost::filesystem::path &root)
Definition utils.cpp:1219
bool open_zip_reader(mz_zip_archive *zip, const std::string &fname)
Definition miniz_extension.cpp:119
bool close_zip_reader(mz_zip_archive *zip)
Definition miniz_extension.cpp:129
bool copy_framework(const std::string &from, const std::string &to)
Definition utils.cpp:1119

References app_config, BAMBU_NETWORK_LIBRARY, Slic3r::close_zip_reader(), Slic3r::copy_file(), Slic3r::copy_framework(), Slic3r::data_dir(), Slic3r::GUI::decode(), Slic3r::encode_path(), get_latest_network_version(), Slic3r::GUI::InstallStatusDownloadFailed, Slic3r::GUI::InstallStatusInstallCompleted, Slic3r::GUI::InstallStatusNormal, Slic3r::GUI::InstallStatusUnzipFailed, Slic3r::is_path_within_root(), Slic3r::is_symlink_target_within_root(), m_networking_cancel_update, Slic3r::open_zip_reader(), and Slic3r::SUCCESS.

Here is the call graph for this function:

◆ is_adding_script_handler()

bool Slic3r::GUI::GUI_App::is_adding_script_handler ( )
inline
774{ return m_adding_script_handler; }
bool m_adding_script_handler
Definition GUI_App.hpp:363

References m_adding_script_handler.

Referenced by run_wizard().

Here is the caller graph for this function:

◆ is_blocking_printing() [1/2]

bool Slic3r::GUI::GUI_App::is_blocking_printing ( MachineObject * obj_,
const std::string & source_model )
2603{
2604 DeviceManager *dev = getDeviceManager();
2605 if (!dev) return true;
2606 if (obj_ == nullptr)
2607 obj_ = dev->get_selected_machine();
2608 if (!obj_)
2609 return false;
2610
2611 return !DevPrinterConfigUtil::is_printer_model_compatible(source_model, *obj_);
2612}
static bool is_printer_model_compatible(const std::string &source_model, MachineObject &machine)
Definition DevConfigUtil.cpp:60
Slic3r::DeviceManager * getDeviceManager()
Definition GUI_App.hpp:404

References Slic3r::DeviceManager::get_selected_machine(), getDeviceManager(), is_blocking_printing(), and Slic3r::DevPrinterConfigUtil::is_printer_model_compatible().

Here is the call graph for this function:

◆ is_blocking_printing() [2/2]

bool Slic3r::GUI::GUI_App::is_blocking_printing ( MachineObject * obj_ = nullptr)
2594{
2595 PresetBundle *preset_bundle = wxGetApp().preset_bundle;
2596 const std::string source_model = preset_bundle
2597 ? preset_bundle->printers.get_edited_preset().get_printer_type(preset_bundle)
2598 : std::string();
2599 return is_blocking_printing(obj_, source_model);
2600}
bool is_blocking_printing(MachineObject *obj_=nullptr)
Definition GUI_App.cpp:2593

References is_blocking_printing(), and preset_bundle.

Referenced by is_blocking_printing(), and is_blocking_printing().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_closing()

◆ is_compatibility_version()

bool Slic3r::GUI::GUI_App::is_compatibility_version ( )
2273{
2274 BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": m_networking_compatible=%1%")%m_networking_compatible;
2276}

References m_networking_compatible.

◆ is_editor()

bool Slic3r::GUI::GUI_App::is_editor ( ) const
inline
426{ return m_app_mode == EAppMode::Editor; }

References Editor, and m_app_mode.

Referenced by Slic3r::anonymous_namespace{PluginHostApp.cpp}::app_info(), logo_name(), on_init_inner(), open_preferences(), post_init(), and recreate_GUI().

Here is the caller graph for this function:

◆ is_enable_multi_machine()

bool Slic3r::GUI::GUI_App::is_enable_multi_machine ( )
inline
388{ return this->app_config&& this->app_config->get("enable_multi_machine") == "true"; }

References app_config.

Referenced by init_networking_callbacks(), on_init_network(), and push_notification().

Here is the caller graph for this function:

◆ is_gcode_viewer()

bool Slic3r::GUI::GUI_App::is_gcode_viewer ( ) const
inline
@ GCodeViewer
Definition GUI_App.hpp:262

References GCodeViewer, and m_app_mode.

Referenced by on_init_inner(), and post_init().

Here is the caller graph for this function:

◆ is_gl_version_greater_or_equal_to()

bool Slic3r::GUI::GUI_App::is_gl_version_greater_or_equal_to ( unsigned int major,
unsigned int minor ) const
inline
837{ return m_opengl_mgr.get_gl_info().is_version_greater_or_equal_to(major, minor); }

References m_opengl_mgr.

◆ is_glsl_version_greater_or_equal_to()

bool Slic3r::GUI::GUI_App::is_glsl_version_greater_or_equal_to ( unsigned int major,
unsigned int minor ) const
inline
838{ return m_opengl_mgr.get_gl_info().is_glsl_version_greater_or_equal_to(major, minor); }

References m_opengl_mgr.

◆ is_localized()

bool Slic3r::GUI::GUI_App::is_localized ( ) const
inline
716{ return m_wxLocale->GetLocale() != "English"; }

References m_wxLocale.

◆ is_recreating_gui()

bool Slic3r::GUI::GUI_App::is_recreating_gui ( ) const
inline
428{ return m_is_recreating_gui; }
bool m_is_recreating_gui
Definition GUI_App.hpp:270

References m_is_recreating_gui.

◆ is_studio_active()

bool Slic3r::GUI::GUI_App::is_studio_active ( )
6178{
6179 auto curr_time = std::chrono::system_clock::now();
6180 auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(curr_time - last_active_point);
6181 if (diff.count() < STUDIO_INACTIVE_TIMEOUT) {
6182 return true;
6183 }
6184 return false;
6185}
#define STUDIO_INACTIVE_TIMEOUT
Definition GUI_App.hpp:50
std::chrono::system_clock::time_point last_active_point
Definition GUI_App.hpp:599
Slic3r::Polygons diff(const Slic3r::Polygon &subject, const Slic3r::Polygon &clip, ApplySafetyOffset do_safety_offset)
Definition ClipperUtils.cpp:731

References Slic3r::diff(), is_studio_active(), last_active_point, and STUDIO_INACTIVE_TIMEOUT.

Referenced by is_studio_active(), and on_init_inner().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_user_login()

bool Slic3r::GUI::GUI_App::is_user_login ( const std::string & provider = ORCA_CLOUD_PROVIDER)
5318{
5319 if (m_agent) {
5320 return m_agent->is_user_login(provider);
5321 }
5322 return false;
5323}

References is_user_login(), and m_agent.

Referenced by Slic3r::anonymous_namespace{PluginHostApp.cpp}::app_info(), is_user_login(), open_mall_page_dialog(), open_publish_page_dialog(), and post_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ keyboard_shortcuts()

void Slic3r::GUI::GUI_App::keyboard_shortcuts ( ShortcutContext page,
wxWindow * parent = nullptr )
4993{
4994 KBShortcutsDialog dlg(parent != nullptr ? parent : mainframe, page);
4995 dlg.ShowModal();
4996}

References keyboard_shortcuts(), mainframe, and Slic3r::GUI::DPIAware< P >::ShowModal().

Referenced by keyboard_shortcuts().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ last_config_version()

const boost::optional< Semver > & Slic3r::GUI::GUI_App::last_config_version ( ) const
inline
411{ return m_last_config_version; }

References m_last_config_version.

Referenced by Slic3r::anonymous_namespace{PluginHostApp.cpp}::app_info().

Here is the caller graph for this function:

◆ link_font()

const wxFont & Slic3r::GUI::GUI_App::link_font ( )
inline
534{ return m_link_font; }
wxFont m_link_font
Definition GUI_App.hpp:297

References m_link_font.

◆ link_to_lan_only_wiki()

std::string Slic3r::GUI::GUI_App::link_to_lan_only_wiki ( )
4839{
4840 std::string url;
4841 std::string country_code = app_config->get_country_code();
4842
4843 if (country_code == "US") {
4844 url = "https://wiki.bambulab.com/en/knowledge-sharing/enable-lan-mode";
4845 }
4846 else if (country_code == "CN") {
4847 url = "https://wiki.bambulab.com/zh/knowledge-sharing/enable-lan-mode";
4848 }
4849 else {
4850 url = "https://wiki.bambulab.com/en/knowledge-sharing/enable-lan-mode";
4851 }
4852 //wxLaunchDefaultBrowser(url);
4853 return url; // ORCA
4854}

References app_config, and link_to_lan_only_wiki().

Referenced by link_to_lan_only_wiki().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ link_to_network_check()

std::string Slic3r::GUI::GUI_App::link_to_network_check ( )
4820{
4821 std::string url;
4822 std::string country_code = app_config->get_country_code();
4823
4824
4825 if (country_code == "US") {
4826 url = "https://status.bambulab.com";
4827 }
4828 else if (country_code == "CN") {
4829 url = "https://status.bambulab.cn";
4830 }
4831 else {
4832 url = "https://status.bambulab.com";
4833 }
4834 //wxLaunchDefaultBrowser(url);
4835 return url; // ORCA
4836}

References app_config, and link_to_network_check().

Referenced by link_to_network_check().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ load_current_presets()

void Slic3r::GUI::GUI_App::load_current_presets ( bool active_preset_combox = false,
bool check_printer_presets = true )
9376{
9377 // check printer_presets for the containing information about "Print Host upload"
9378 // and create physical printer from it, if any exists
9379 if (check_printer_presets_)
9381
9382 auto& edited_printer_preset = preset_bundle->printers.get_edited_preset();
9383 PrinterTechnology printer_technology = edited_printer_preset.printer_technology();
9384 // ORCA: Sync filament count with the printer's nozzle count before loading presets for multi-tool printers.
9385 // This ensures filament_presets vector is properly sized when combo boxes are created/updated.
9386 if (printer_technology == ptFFF && !edited_printer_preset.config.opt_bool("single_extruder_multi_material")) {
9387 auto* nozzle_diameter = edited_printer_preset.config.option<ConfigOptionFloats>("nozzle_diameter");
9388 if (nozzle_diameter) {
9389 // Mixed-color slots are virtual filaments kept at the tail of the list, so they have no
9390 // nozzle of their own and the count has to allow for them. Only ever grow: this sizes
9391 // the list so the combo boxes have something to bind to, and set_num_filaments() trims
9392 // at the raw tail, so shrinking here would eat the mixes rather than the surplus
9393 // physical slots. A list longer than the nozzle count is a state the app reaches
9394 // legitimately - raising the extruder count and not saving the printer preset leaves
9395 // exactly that on the next start - and losing the project's mixes to it is worse than
9396 // carrying a filament the printer has no nozzle for until the count is next changed.
9397 const size_t target = nozzle_diameter->values.size() + preset_bundle->num_mixed_filaments();
9398 if (target > preset_bundle->filament_presets.size())
9399 preset_bundle->set_num_filaments(target);
9400 }
9401 }
9403 for (Tab *tab : tabs_list)
9404 if (tab->supports_printer_technology(printer_technology)) {
9405 if (tab->type() == Preset::TYPE_PRINTER) {
9406 static_cast<TabPrinter*>(tab)->update_pages();
9407 // Mark the plater to update print bed by tab->load_current_preset() from Plater::on_config_change().
9408 this->plater()->force_print_bed_update();
9409 }
9410 tab->load_current_preset();
9411 //BBS: add preset combox re-active logic
9412 if (active_preset_combox)
9413 tab->reactive_preset_combo_box();
9414 }
9415 // Preset loading can resize the filament list without an extruder-count change event.
9416 // Refresh the controls even when the list already matches the printer's nozzle count.
9418 this->plater()->on_filament_count_change(preset_bundle->filament_presets.size());
9419
9420 // BBS: model config
9421 for (Tab *tab : model_tabs_list)
9422 if (tab->supports_printer_technology(printer_technology)) {
9423 tab->rebuild_page_tree();
9424 }
9425}
void check_printer_presets()
Definition GUI_App.cpp:4906
void force_print_bed_update()
Definition Plater.cpp:21784
void on_filament_count_change(size_t extruders_count)
Definition Plater.cpp:21374
bool set_printer_technology(PrinterTechnology printer_technology)
Definition Plater.cpp:22162
@ ptFFF
Definition Config.hpp:231

References check_printer_presets(), load_current_presets(), model_tabs_list, Slic3r::nozzle_diameter(), plater(), preset_bundle, Slic3r::GUI::printer_technology(), Slic3r::ptFFF, tabs_list, and Slic3r::Preset::TYPE_PRINTER.

Referenced by apply_keeped_preset_modifications(), check_and_keep_current_preset_changes(), check_and_save_current_preset_changes(), load_current_presets(), on_init_inner(), recreate_GUI(), run_wizard(), ShowOnlyFilament(), and ShowUserGuide().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ load_gcode()

void Slic3r::GUI::GUI_App::load_gcode ( wxWindow * parent,
wxString & input_file ) const
5248{
5249 input_file.Clear();
5250 wxFileDialog dialog(parent ? parent : GetTopWindow(),
5251 _L("Choose one file (GCODE/3MF):"),
5252 app_config->get_last_dir(), "",
5253 file_wildcards(FT_GCODE), wxFD_OPEN | wxFD_FILE_MUST_EXIST);
5254
5255 if (dialog.ShowModal() == wxID_OK)
5256 input_file = dialog.GetPath();
5257}
@ FT_GCODE
Definition GUI_App.hpp:126

References _L, app_config, Slic3r::GUI::file_wildcards(), Slic3r::GUI::FT_GCODE, and load_gcode().

Referenced by load_gcode().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ load_language()

bool Slic3r::GUI::GUI_App::load_language ( wxString language,
bool initial )
8463{
8464 BOOST_LOG_TRIVIAL(info) << boost::format("%1%: language %2%, initial: %3%") %__FUNCTION__ %language %initial;
8465 if (initial) {
8466 // There is a static list of lookup path prefixes in wxWidgets. Add ours.
8467 wxFileTranslationsLoader::AddCatalogLookupPathPrefix(from_u8(localization_dir()));
8468 // Get the active language from PrusaSlicer.ini, or empty string if the key does not exist.
8469 language = app_config->get("language");
8470 if (! language.empty())
8471 BOOST_LOG_TRIVIAL(info) << boost::format("language provided by OrcaSlicer.conf: %1%") % language;
8472 else {
8473 // Get the system language.
8474 const wxLanguage lang_system = wxLanguage(wxLocale::GetSystemLanguage());
8475 if (lang_system != wxLANGUAGE_UNKNOWN) {
8476 m_language_info_system = wxLocale::GetLanguageInfo(lang_system);
8477#ifdef __WXMSW__
8478 WCHAR wszLanguagesBuffer[LOCALE_NAME_MAX_LENGTH];
8479 ::LCIDToLocaleName(LOCALE_USER_DEFAULT, wszLanguagesBuffer, LOCALE_NAME_MAX_LENGTH, 0);
8480 wxString lang(wszLanguagesBuffer);
8481 lang.Replace('-', '_');
8482 if (auto info = wxLocale::FindLanguageInfo(lang))
8484#endif
8485 BOOST_LOG_TRIVIAL(info) << boost::format("System language detected (user locales and such): %1%") % m_language_info_system->CanonicalName.ToUTF8().data();
8486 // BBS set language to app config
8487 app_config->set("language", m_language_info_system->CanonicalName.ToUTF8().data());
8488 } else {
8489 {
8490 // Allocating a temporary locale will switch the default wxTranslations to its internal wxTranslations instance.
8491 wxLocale temp_locale;
8492 temp_locale.Init();
8493 // Set the current translation's language to default, otherwise GetBestTranslation() may not work (see the wxWidgets source code).
8494 wxTranslations::Get()->SetLanguage(wxLANGUAGE_DEFAULT);
8495 // Let the wxFileTranslationsLoader enumerate all translation dictionaries for PrusaSlicer
8496 // and try to match them with the system specific "preferred languages".
8497 // There seems to be a support for that on Windows and OSX, while on Linuxes the code just returns wxLocale::GetSystemLanguage().
8498 // The last parameter gets added to the list of detected dictionaries. This is a workaround
8499 // for not having the English dictionary. Let's hope wxWidgets of various versions process this call the same way.
8500 wxString best_language = wxTranslations::Get()->GetBestTranslation(SLIC3R_APP_KEY, wxLANGUAGE_ENGLISH);
8501 if (!best_language.IsEmpty()) {
8502 m_language_info_best = wxLocale::FindLanguageInfo(best_language);
8503 BOOST_LOG_TRIVIAL(info) << boost::format("Best translation language detected (may be different from user locales): %1%") %
8504 m_language_info_best->CanonicalName.ToUTF8().data();
8505 app_config->set("language", m_language_info_best->CanonicalName.ToUTF8().data());
8506 }
8507#ifdef __linux__
8508 wxString lc_all;
8509 if (wxGetEnv("LC_ALL", &lc_all) && !lc_all.IsEmpty()) {
8510 // Best language returned by wxWidgets on Linux apparently does not respect LC_ALL.
8511 // Disregard the "best" suggestion in case LC_ALL is provided.
8512 m_language_info_best = nullptr;
8513 }
8514#endif
8515 }
8516 }
8517 }
8518 }
8519
8520 const wxLanguageInfo *language_info = language.empty() ? nullptr : wxLocale::FindLanguageInfo(language);
8521 if (! language.empty() && (language_info == nullptr || language_info->CanonicalName.empty())) {
8522 // Fix for wxWidgets issue, where the FindLanguageInfo() returns locales with undefined ANSII code (wxLANGUAGE_KONKANI or wxLANGUAGE_MANIPURI).
8523 language_info = nullptr;
8524 BOOST_LOG_TRIVIAL(error) << boost::format("Language code \"%1%\" is not supported") % language.ToUTF8().data();
8525 }
8526
8527 if (language_info != nullptr && language_info->LayoutDirection == wxLayout_RightToLeft) {
8528 BOOST_LOG_TRIVIAL(trace) << boost::format("The following language code requires right to left layout, which is not supported by OrcaSlicer: %1%") % language_info->CanonicalName.ToUTF8().data();
8529 language_info = nullptr;
8530 }
8531
8532 if (language_info == nullptr) {
8533 // PrusaSlicer does not support the Right to Left languages yet.
8534 if (m_language_info_system != nullptr && m_language_info_system->LayoutDirection != wxLayout_RightToLeft)
8535 language_info = m_language_info_system;
8536 if (m_language_info_best != nullptr && m_language_info_best->LayoutDirection != wxLayout_RightToLeft)
8537 language_info = m_language_info_best;
8538 if (language_info == nullptr)
8539 language_info = wxLocale::GetLanguageInfo(wxLANGUAGE_ENGLISH_US);
8540 }
8541
8542 const wxLanguageInfo *translation_language_info = language_info;
8543 const wxString requested_language_code = translation_language_info->CanonicalName;
8544 const wxLanguageInfo *locale_language_info = translation_language_info;
8545 BOOST_LOG_TRIVIAL(trace) << boost::format("Requested translation language %1%") % requested_language_code.ToUTF8().data();
8546
8547 // Select language for locales. This language may be different from the language of the dictionary.
8548 //if (language_info == m_language_info_best || language_info == m_language_info_system) {
8549 // // The current language matches user's default profile exactly. That's great.
8550 //} else if (m_language_info_best != nullptr && language_info->CanonicalName.BeforeFirst('_') == m_language_info_best->CanonicalName.BeforeFirst('_')) {
8551 // // Use whatever the operating system recommends, if it the language code of the dictionary matches the recommended language.
8552 // // This allows a Swiss guy to use a German dictionary without forcing him to German locales.
8553 // language_info = m_language_info_best;
8554 //} else if (m_language_info_system != nullptr && language_info->CanonicalName.BeforeFirst('_') == m_language_info_system->CanonicalName.BeforeFirst('_'))
8555 // language_info = m_language_info_system;
8556
8557 // Alternate language code.
8558 wxLanguage language_dict = wxLanguage(translation_language_info->Language);
8559 if (translation_language_info->CanonicalName.BeforeFirst('_') == "sk") {
8560 // Slovaks understand Czech well. Give them the Czech translation.
8561 language_dict = wxLANGUAGE_CZECH;
8562 BOOST_LOG_TRIVIAL(info) << "Using Czech dictionaries for Slovak language";
8563 }
8564
8565#ifdef __linux__
8566 // If we can't find this locale , try to use different one for the language
8567 // instead of just reporting that it is impossible to switch.
8568 if (!wxLocale::IsAvailable(locale_language_info->Language) && m_language_info_system) {
8569 std::string original_lang = into_u8(locale_language_info->CanonicalName);
8570 locale_language_info = linux_get_existing_locale_language(locale_language_info, m_language_info_system);
8571 if (locale_language_info != nullptr && locale_language_info != translation_language_info) {
8572 BOOST_LOG_TRIVIAL(info) << boost::format("Can't use locale %1% directly (missing locales). Using locale %2% instead.")
8573 % original_lang % locale_language_info->CanonicalName.ToUTF8().data();
8574 }
8575 }
8576#endif
8577
8578 // Try base language without region (e.g., "en" from "en_IL") on all platforms
8579 if (locale_language_info == nullptr || !wxLocale::IsAvailable(locale_language_info->Language)) {
8580 wxString base_lang = requested_language_code.BeforeFirst('_');
8581 if (base_lang != requested_language_code) {
8582 const wxLanguageInfo *base_info = wxLocale::FindLanguageInfo(base_lang);
8583 if (base_info && wxLocale::IsAvailable(base_info->Language)) {
8584 BOOST_LOG_TRIVIAL(info) << boost::format("Locale %1% not available. Falling back to base language %2%.")
8585 % requested_language_code.ToUTF8().data() % base_info->CanonicalName.ToUTF8().data();
8586 locale_language_info = base_info;
8587 }
8588 }
8589 }
8590
8591 // Generic fallback chain for all platforms
8592 if (locale_language_info == nullptr || !wxLocale::IsAvailable(locale_language_info->Language)) {
8593 auto try_locale = [](const wxLanguageInfo* candidate) -> const wxLanguageInfo* {
8594 return (candidate && wxLocale::IsAvailable(candidate->Language)) ? candidate : nullptr;
8595 };
8596 const wxLanguageInfo* fallback_locale_info =
8597 try_locale(m_wxLocale ? wxLocale::GetLanguageInfo(wxLanguage(m_wxLocale->GetLanguage())) : nullptr);
8598 if (!fallback_locale_info) fallback_locale_info = try_locale(m_language_info_system);
8599 if (!fallback_locale_info) fallback_locale_info = try_locale(m_language_info_best);
8600 if (!fallback_locale_info) fallback_locale_info = try_locale(wxLocale::GetLanguageInfo(wxLANGUAGE_ENGLISH_US));
8601 if (!fallback_locale_info) fallback_locale_info = try_locale(wxLocale::GetLanguageInfo(wxLANGUAGE_ENGLISH_UK));
8602 if (fallback_locale_info != nullptr) {
8603 BOOST_LOG_TRIVIAL(info) << boost::format("Using fallback locale %1% while keeping translation dictionary %2%.")
8604 % fallback_locale_info->CanonicalName.ToUTF8().data() % requested_language_code.ToUTF8().data();
8605 locale_language_info = fallback_locale_info;
8606 }
8607 }
8608
8609 if (initial) {
8610 // bbs supported languages
8611 //TODO: use a global one with Preference
8612 //wxLanguage supported_languages[]{
8613 // wxLANGUAGE_ENGLISH,
8614 // wxLANGUAGE_CHINESE_SIMPLIFIED,
8615 // wxLANGUAGE_GERMAN,
8616 // wxLANGUAGE_FRENCH,
8617 // wxLANGUAGE_SPANISH,
8618 // wxLANGUAGE_SWEDISH,
8619 // wxLANGUAGE_DUTCH,
8620 // wxLANGUAGE_HUNGARIAN,
8621 // wxLANGUAGE_JAPANESE,
8622 // wxLANGUAGE_ITALIAN
8623 //};
8624 //std::string cur_language = app_config->get("language");
8625 //if (cur_language != "") {
8626 // //cleanup the language wrongly set before
8627 // const wxLanguageInfo *langinfo = nullptr;
8628 // bool embedded_language = false;
8629 // int language_num = sizeof(supported_languages) / sizeof(supported_languages[0]);
8630 // for (auto index = 0; index < language_num; index++) {
8631 // langinfo = wxLocale::GetLanguageInfo(supported_languages[index]);
8632 // std::string temp_lan = langinfo->CanonicalName.ToUTF8().data();
8633 // if (cur_language == temp_lan) {
8634 // embedded_language = true;
8635 // break;
8636 // }
8637 // }
8638 // if (!embedded_language)
8639 // app_config->erase("app", "language");
8640 //}
8641 }
8642
8643 BOOST_LOG_TRIVIAL(trace) << boost::format("Switching wxLocales to %1%") % locale_language_info->CanonicalName.ToUTF8().data();
8644
8645 if (!wxLocale::IsAvailable(locale_language_info->Language)) {
8646 // Loading the language dictionary failed.
8647 wxString message = wxString::Format(_L("Switching Orca Slicer to language %s failed."), requested_language_code);
8648#if !defined(_WIN32) && !defined(__APPLE__)
8649 // likely some linux system
8650 message += _L("\nYou may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n");
8651#endif
8652 if (initial)
8653 message += "\n\n" + _L("Application will close.");
8654 wxMessageBox(message, _L("Orca Slicer - Switching language failed"), wxOK | wxICON_ERROR);
8655 if (initial)
8656 std::exit(EXIT_FAILURE);
8657 else
8658 return false;
8659 }
8660
8661 // Release the old locales, create new locales.
8662 //FIXME wxWidgets cause havoc if the current locale is deleted. We just forget it causing memory leaks for now.
8663 m_wxLocale.release();
8665 m_wxLocale->Init(locale_language_info->Language);
8666 // Override language at the active wxTranslations class (which is stored in the active m_wxLocale)
8667 // to load possibly different dictionary, for example, load Czech dictionary for Slovak language.
8668 wxTranslations::Get()->SetLanguage(language_dict);
8669 m_wxLocale->AddCatalog(SLIC3R_APP_KEY);
8670 m_active_language_code = requested_language_code;
8671 m_imgui->set_language(into_u8(requested_language_code));
8672
8673 //FIXME This is a temporary workaround, the correct solution is to switch to "C" locale during file import / export only.
8674 //wxSetlocale(LC_NUMERIC, "C");
8675 Preset::update_suffix_modified((_L("*") + " ").ToUTF8().data());
8677 return true;
8678}
const wxLanguageInfo * m_language_info_system
Definition GUI_App.hpp:304
const wxLanguageInfo * m_language_info_best
Definition GUI_App.hpp:306
void reinit()
Definition HintNotification.cpp:328
static HintDatabase & get_instance()
Definition HintNotification.hpp:44
static void update_suffix_modified(const std::string &new_suffix_modified)
Definition Preset.cpp:510
void trace(unsigned int level, const char *message)
Definition utils.cpp:247
std::unique_ptr< T > make_unique(Args &&... args)
Definition libslic3r.h:239
const std::string & localization_dir()
Definition utils.cpp:320

References _L, app_config, Slic3r::GUI::from_u8(), Slic3r::GUI::HintDatabase::get_instance(), Slic3r::GUI::into_u8(), load_language(), Slic3r::localization_dir(), m_active_language_code, m_imgui, m_language_info_best, m_language_info_system, m_wxLocale, Slic3r::make_unique(), Slic3r::trace(), and Slic3r::Preset::update_suffix_modified().

Referenced by load_language(), on_init_inner(), and open_preferences().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ load_pending_vendors()

void Slic3r::GUI::GUI_App::load_pending_vendors ( )
7430{
7431 if (need_add_vendors.size() == 0 && need_add_filaments.size() == 0)
7432 return;
7433
7434 preset_bundle->apply_vendor_config(need_add_vendors, need_add_filaments, app_config, false);
7436 app_config->save();
7437 else
7438 CallAfter([this] { app_config->save(); });
7439 need_add_vendors.clear();
7440 need_add_filaments.clear();
7441}
bool is_main_thread_active()
Definition Thread.cpp:218

References app_config, Slic3r::is_main_thread_active(), load_pending_vendors(), need_add_filaments, need_add_vendors, and preset_bundle.

Referenced by load_pending_vendors(), reload_settings(), sync_bundle(), and update_single_bundle().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ load_project()

void Slic3r::GUI::GUI_App::load_project ( wxWindow * parent,
wxString & input_file ) const
5209{
5210 input_file.Clear();
5211 wxFileDialog dialog(parent ? parent : GetTopWindow(),
5212 _L("Choose one file (3MF):"),
5213 app_config->get_last_dir(), "",
5214 file_wildcards(FT_PROJECT), wxFD_OPEN | wxFD_FILE_MUST_EXIST);
5215
5216 if (dialog.ShowModal() == wxID_OK)
5217 input_file = dialog.GetPath();
5218}
@ FT_PROJECT
Definition GUI_App.hpp:129

References _L, app_config, Slic3r::GUI::file_wildcards(), Slic3r::GUI::FT_PROJECT, and load_project().

Referenced by load_project().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ load_url()

void Slic3r::GUI::GUI_App::load_url ( wxString url)
9744{
9745 if (mainframe)
9746 return mainframe->load_url(url);
9747}

References load_url(), and mainframe.

Referenced by load_url().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ logo_name()

std::string Slic3r::GUI::GUI_App::logo_name ( ) const
inline
434{ return is_editor() ? "OrcaSlicer" : "OrcaSlicer-gcodeviewer"; }
bool is_editor() const
Definition GUI_App.hpp:426

References is_editor().

Here is the call graph for this function:

◆ may_switch_to_SLA_preset()

bool Slic3r::GUI::GUI_App::may_switch_to_SLA_preset ( const wxString & caption)
9957{
9959 // BBS: remove SLA related message
9960 return false;
9961 }
9962 return true;
9963}
Model & model()
Definition GUI_App.cpp:9733
bool model_has_multi_part_objects(const Model &model)
Definition Model.cpp:4311

References may_switch_to_SLA_preset(), model(), and Slic3r::model_has_multi_part_objects().

Referenced by may_switch_to_SLA_preset().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ maybe_migrate_user_presets_on_login()

bool Slic3r::GUI::GUI_App::maybe_migrate_user_presets_on_login ( )
7189{
7190 namespace fs = boost::filesystem;
7191
7192 BOOST_LOG_TRIVIAL(info) << "Migrate user presets to the OrcaCloud user folder if needed.";
7193
7194 if (!m_agent || !m_agent->is_user_login())
7195 return false;
7196
7197 std::string new_user_id = m_agent->get_user_id();
7198 if (new_user_id.empty()) {
7199 BOOST_LOG_TRIVIAL(warning) << "Failed to get user ID, skipping migration.";
7200 return false;
7201 }
7202
7203 fs::path user_base = fs::path(data_dir()) / PRESET_USER_DIR;
7204 fs::path target_dir = user_base / new_user_id;
7205
7206 // Check if the user already has presets on OrcaCloud.
7207 // We must query the cloud (not the local folder) to avoid overwriting existing cloud profiles
7208 // that haven't been synced down yet (e.g. fresh install with existing cloud account).
7209 {
7210 std::map<std::string, std::map<std::string, std::string>> cloud_presets;
7211 int ret = m_agent->get_user_presets(&cloud_presets);
7212 if (ret == 0 && !cloud_presets.empty()) {
7213 BOOST_LOG_TRIVIAL(info) << "OrcaCloud already has " << cloud_presets.size()
7214 << " presets, skipping migration for user: " << new_user_id;
7215 return false;
7216 }
7217 if (ret != 0) {
7218 BOOST_LOG_TRIVIAL(warning) << "Failed to query OrcaCloud presets (error " << ret
7219 << "), skipping migration to avoid overwriting cloud data.";
7220 // If this looks like a transient 401 from token propagation delay (within grace period),
7221 // schedule one deferred retry so first-time users don't silently lose their preset migration.
7222 if (std::chrono::steady_clock::now() - m_last_401_error_time < std::chrono::seconds(30)
7223 && !m_migration_retry_pending.exchange(true)) {
7224 BOOST_LOG_TRIVIAL(info) << "Scheduling migration retry after token propagation window.";
7225 boost::thread([this]() {
7226 std::this_thread::sleep_for(std::chrono::seconds(5));
7227 CallAfter([this]() {
7229 if (is_closing() || !m_agent || !m_agent->is_user_login()) return;
7230 BOOST_LOG_TRIVIAL(info) << "Retrying preset migration after token propagation window.";
7232 const std::string user_id = m_agent->get_user_id();
7234 if (mainframe) mainframe->update_side_preset_ui();
7235 }
7236 });
7237 }).detach();
7238 }
7239 return false;
7240 }
7241 BOOST_LOG_TRIVIAL(info) << "OrcaCloud has no presets for user " << new_user_id << ", proceeding with migration check.";
7242 }
7243
7244 // Helper to check if a local directory has any .json preset files.
7245 auto has_json_presets = [](const fs::path& dir) -> bool {
7246 try {
7247 if (!fs::exists(dir) || !fs::is_directory(dir))
7248 return false;
7249 boost::system::error_code ec;
7250 for (auto it = fs::recursive_directory_iterator(dir, ec); it != fs::recursive_directory_iterator(); it.increment(ec)) {
7251 if (ec) {
7252 BOOST_LOG_TRIVIAL(warning) << "Error scanning directory " << dir << ": " << ec.message();
7253 continue;
7254 }
7255 if (fs::is_regular_file(*it) && it->path().extension() == ".json")
7256 return true;
7257 }
7258 } catch (const fs::filesystem_error& e) {
7259 BOOST_LOG_TRIVIAL(warning) << "Failed to scan directory for presets: " << e.what();
7260 }
7261 return false;
7262 };
7263
7264 // Determine the source directory to migrate from.
7265 // Priority: 1) Bambu Cloud user folder (if user was logged in), 2) "default" folder, 3) any other user-ID folder
7266 fs::path source_dir;
7267 bool source_is_default = false;
7268 bool source_is_bbl = false;
7269 fs::path default_dir = user_base / DEFAULT_USER_FOLDER_NAME;
7270
7271 // Check if the user was previously logged into Bambu Cloud and has presets there
7272 if (m_agent->is_user_login(BBL_CLOUD_PROVIDER)) {
7273 std::string bbl_user_id = m_agent->get_user_id(BBL_CLOUD_PROVIDER);
7274 if (!bbl_user_id.empty() && bbl_user_id != new_user_id) {
7275 fs::path bbl_dir = user_base / bbl_user_id;
7276 if (has_json_presets(bbl_dir)) {
7277 source_dir = bbl_dir;
7278 source_is_bbl = true;
7279 BOOST_LOG_TRIVIAL(info) << "Migration source: Bambu Cloud user folder: " << source_dir;
7280 }
7281 }
7282 }
7283
7284 // Fallback to default folder
7285 if (source_dir.empty() && has_json_presets(default_dir)) {
7286 source_dir = default_dir;
7287 source_is_default = true;
7288 BOOST_LOG_TRIVIAL(info) << "Migration source: default user folder: " << source_dir;
7289 }
7290
7291 // Last resort: scan for any other user-ID folder with presets
7292 if (source_dir.empty() && fs::exists(user_base) && fs::is_directory(user_base)) {
7293 for (auto& entry : fs::directory_iterator(user_base)) {
7294 if (!fs::is_directory(entry))
7295 continue;
7296 std::string folder_name = entry.path().filename().string();
7297 if (folder_name == new_user_id || folder_name == DEFAULT_USER_FOLDER_NAME)
7298 continue;
7299 if (has_json_presets(entry.path())) {
7300 source_dir = entry.path();
7301 BOOST_LOG_TRIVIAL(info) << "Migration source: user folder: " << source_dir;
7302 break;
7303 }
7304 }
7305 }
7306
7307 if (source_dir.empty()) {
7308 BOOST_LOG_TRIVIAL(info) << "No existing user presets found to migrate.";
7309 return false;
7310 }
7311
7312 // Ask the user for confirmation with a message tailored to the source type
7313 wxString source_description;
7314 if (source_is_bbl) {
7315 source_description = wxString::Format(
7316 _L("your Orca Cloud profile (user ID: \"%s\")"),
7317 from_u8(source_dir.filename().string()));
7318 } else if (source_is_default) {
7319 source_description = _L("your default profile");
7320 } else {
7321 source_description = wxString::Format(
7322 _L("a user profile (folder: \"%s\")"),
7323 from_u8(source_dir.filename().string()));
7324 }
7325
7326 wxString msg = wxString::Format(
7327 _L("Existing user presets were found in %s.\n"
7328 "Do you want to migrate them to your OrcaCloud profile?\n"
7329 "This will copy your presets so they are available under your new account."),
7330 source_description);
7331
7332 MessageDialog dlg(mainframe, msg, _L("Migrate User Presets"),
7333 wxCENTER | wxYES_DEFAULT | wxYES_NO | wxICON_INFORMATION);
7334 if (dlg.ShowModal() != wxID_YES) {
7335 BOOST_LOG_TRIVIAL(info) << "User declined preset migration.";
7336 return false;
7337 }
7338
7339 // Perform the migration using copy_directory_recursively in merge mode
7340 // to preserve any existing files (e.g. .info sync markers) in the target directory.
7341 try {
7342 wxBusyCursor busy;
7343 BOOST_LOG_TRIVIAL(info) << "Migrating user presets from " << source_dir << " to " << target_dir;
7344
7345 auto info_filter = [](const std::string& filename) -> bool {
7346 // Return true to skip .info files
7347 return filename.size() >= 5 &&
7348 filename.compare(filename.size() - 5, 5, ".info") == 0;
7349 };
7350
7351 copy_directory_recursively(source_dir, target_dir, info_filter, /*merge_mode=*/true);
7352 BOOST_LOG_TRIVIAL(info) << "User preset migration completed successfully.";
7353 } catch (const std::exception& ex) {
7354 BOOST_LOG_TRIVIAL(error) << "Failed to migrate user presets: " << ex.what();
7355 wxString err_msg = wxString::Format(
7356 _L("Failed to migrate user presets:\n%s"),
7357 from_u8(ex.what()));
7358 show_error(nullptr, err_msg);
7359 return false;
7360 }
7361
7362 return true;
7363}
#define PRESET_USER_DIR
Definition Preset.hpp:32
std::atomic< bool > m_migration_retry_pending
Definition GUI_App.hpp:361
std::chrono::steady_clock::time_point m_last_401_error_time
Definition GUI_App.hpp:366
bool maybe_migrate_user_presets_on_login()
Definition GUI_App.cpp:7188
@ Enable
Definition Config.hpp:245
void copy_directory_recursively(const boost::filesystem::path &source, const boost::filesystem::path &target, std::function< bool(const std::string)> filter, bool merge_mode)
Definition utils.cpp:1924

References _L, Slic3r::BBL_CLOUD_PROVIDER(), Slic3r::copy_directory_recursively(), Slic3r::data_dir(), DEFAULT_USER_FOLDER_NAME, Slic3r::Enable, Slic3r::GUI::from_u8(), is_closing(), m_agent, m_last_401_error_time, m_migration_retry_pending, mainframe, maybe_migrate_user_presets_on_login(), preset_bundle, PRESET_USER_DIR, Slic3r::GUI::show_error(), and Slic3r::GUI::DPIAware< P >::ShowModal().

Referenced by maybe_migrate_user_presets_on_login(), and on_user_login_handle().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ migrate_network_plugin_config()

void Slic3r::GUI::GUI_App::migrate_network_plugin_config ( )
1981{
1982 if (!app_config)
1983 return;
1984
1985 const std::string cfg = app_config->get_network_plugin_version();
1987 return; // empty / legacy / custom-named / unsupported old series -> nothing to migrate here
1988 // (an unsupported old config is handled by the fallback in on_init_network)
1989
1990 const std::string series = network_plugin_series(cfg);
1991 if (cfg != series) {
1992 app_config->set_network_plugin_version(series);
1993 app_config->save();
1994 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": network_plugin_version " << cfg << " -> " << series;
1995 }
1996
1997 // Consolidate the on-disk files onto the series name. Runs at startup before the plug-in is
1998 // loaded, so the rename is safe even on Windows (nothing holds the file open yet). If it is
1999 // skipped or fails, resolve_library_path() still loads the specific build for this series.
2000 std::string newest;
2001 for (const auto& v : BBLNetworkPlugin::scan_plugin_versions())
2002 if (is_series_managed_version(v) && network_plugin_series(v) == series && (newest.empty() || v > newest))
2003 newest = v;
2004 if (newest.empty())
2005 return;
2006
2007 boost::system::error_code ec;
2008 const boost::filesystem::path series_path(BBLNetworkPlugin::get_versioned_library_path(series));
2009 if (newest != series) {
2010 // Make the newest same-series build the series file. Safe here (pre-load); if the rename
2011 // fails, resolve_library_path() still loads the specific build for this series.
2012 boost::filesystem::remove(series_path, ec);
2013 boost::filesystem::rename(BBLNetworkPlugin::get_versioned_library_path(newest), series_path, ec);
2014 if (ec)
2015 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": rename " << newest << " -> " << series
2016 << " failed (" << ec.message() << "), loader will resolve it";
2017 }
2018
2019 // Tidy strictly-older same-series managed builds (best-effort; never touch custom/legacy).
2020 for (const auto& v : BBLNetworkPlugin::scan_plugin_versions()) {
2021 if (v == series || !is_series_managed_version(v) || network_plugin_series(v) != series)
2022 continue;
2023 boost::filesystem::remove(BBLNetworkPlugin::get_versioned_library_path(v), ec);
2024 }
2025}
static std::string get_versioned_library_path(const std::string &version)
Definition BBLNetworkPlugin.cpp:403
static std::vector< std::string > scan_plugin_versions()
Definition BBLNetworkPlugin.cpp:489
bool is_series_managed_version(const std::string &version)
Definition bambu_networking.hpp:538

References app_config, Slic3r::BBLNetworkPlugin::get_versioned_library_path(), Slic3r::is_series_managed_version(), Slic3r::is_supported_network_version(), Slic3r::network_plugin_series(), and Slic3r::BBLNetworkPlugin::scan_plugin_versions().

Referenced by on_init_network().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mint_cloud_web_session()

void Slic3r::GUI::GUI_App::mint_cloud_web_session ( const std::string & state,
uint64_t gen )
6037{
6038 auto orca = get_orca_cloud_agent(m_agent);
6039 if (!orca)
6040 return;
6041
6042 // The endpoint call blocks on network I/O (and possibly a cross-process token refresh), so
6043 // it must not run on the UI thread. Hand off to a worker and marshal the token back.
6044 boost::thread([this, orca, state, gen]() {
6045 std::string token_hash;
6046 std::string error_code;
6047 unsigned int http_code = 0;
6048 orca->request_web_session_handoff(token_hash, error_code, http_code);
6049
6050 if (is_closing())
6051 return;
6052
6053 if (token_hash.empty()) {
6054 // No token: 401 after retry, 409/429/503 or a transport error. The page owns its own
6055 // "Sign-in link expired"/"Try again" UI; the desktop stays silent. Never log the body
6056 // (it may echo account data), only the status/error code.
6057 BOOST_LOG_TRIVIAL(warning) << "cloud web session handoff not minted - http_code=" << http_code
6058 << " error_code=" << error_code;
6059 return;
6060 }
6061
6062 GUI::wxGetApp().CallAfter([this, state, gen, token_hash]() {
6063 on_cloud_web_session_minted(state, gen, token_hash);
6064 });
6065 }).detach();
6066}
void on_cloud_web_session_minted(const std::string &state, uint64_t gen, const std::string &token_hash)
Definition GUI_App.cpp:6068

References Slic3r::GUI::get_orca_cloud_agent(), is_closing(), m_agent, mint_cloud_web_session(), and on_cloud_web_session_minted().

Referenced by mint_cloud_web_session(), and request_cloud_web_session().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ model()

Model & Slic3r::GUI::GUI_App::model ( )
9734{
9735 return plater_->model();
9736}

References model(), and plater_.

Referenced by may_switch_to_SLA_preset(), and model().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ no_new_version()

void Slic3r::GUI::GUI_App::no_new_version ( )
6927{
6928 wxCommandEvent* evt = new wxCommandEvent(EVT_SHOW_NO_NEW_VERSION);
6929 GUI::wxGetApp().QueueEvent(evt);
6930}

References no_new_version().

Referenced by check_new_version(), check_new_version_sf(), check_update(), and no_new_version().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ normal_font()

const wxFont & Slic3r::GUI::GUI_App::normal_font ( )
inline
532{ return m_normal_font; }

References m_normal_font.

Referenced by Slic3r::GUI::anonymous_namespace{WebViewHostDialog.cpp}::host_theme_vars_css().

Here is the caller graph for this function:

◆ notification_manager()

NotificationManager * Slic3r::GUI::GUI_App::notification_manager ( )
9879{
9880 if (plater_)
9881 return plater_->get_notification_manager();
9882 return nullptr;
9883}

References notification_manager(), and plater_.

Referenced by notification_manager().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ obj_layers()

ObjectLayers * Slic3r::GUI::GUI_App::obj_layers ( )
9705{
9706 return sidebar().obj_layers();
9707}
Sidebar & sidebar()
Definition GUI_App.cpp:9683
ObjectLayers * obj_layers()
Definition Plater.cpp:6650

References obj_layers(), and sidebar().

Referenced by obj_layers().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ obj_list()

ObjectList * Slic3r::GUI::GUI_App::obj_list ( )
9700{
9701 return sidebar().obj_list();
9702}
ObjectList * obj_list()
Definition Plater.cpp:6638

References obj_list(), and sidebar().

Referenced by anonymous_namespace{EmbossJob.cpp}::create_volume(), Slic3r::GUI::GLGizmoEmboss::draw_model_type(), Slic3r::GUI::GLGizmoSVG::draw_model_type(), anonymous_namespace{EmbossJob.cpp}::CreateObjectJob::finalize(), obj_list(), on_init_inner(), on_shortcuts_changed(), recreate_GUI(), and Slic3r::GUI::Emboss::UpdateJob::update_volume().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ obj_manipul()

GizmoObjectManipulation * Slic3r::GUI::GUI_App::obj_manipul ( )
9689{
9690 // If this method is called before plater_ has been initialized, return nullptr (to avoid a crash)
9691 return (plater_ != nullptr) ? &plater_->get_view3D_canvas3D()->get_gizmos_manager().get_object_manipulation() : nullptr;
9692}

References obj_manipul(), and plater_.

Referenced by obj_manipul().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ obj_settings()

ObjectSettings * Slic3r::GUI::GUI_App::obj_settings ( )
9695{
9696 return sidebar().obj_settings();
9697}
ObjectSettings * obj_settings()
Definition Plater.cpp:6645

References obj_settings(), and sidebar().

Referenced by obj_settings().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_check_privacy_update()

void Slic3r::GUI::GUI_App::on_check_privacy_update ( wxCommandEvent & evt)
6860{
6861 int online_login = evt.GetInt();
6862 std::string provider = evt.GetString().ToStdString();
6863 if (provider.empty()) provider = ORCA_CLOUD_PROVIDER;
6864 bool result = check_privacy_update();
6865 if (result)
6866 on_show_check_privacy_dlg(online_login, provider);
6867 else
6868 request_user_handle(online_login, provider);
6869}
bool check_privacy_update()
Definition GUI_App.cpp:6841
void on_show_check_privacy_dlg(int online_login=0, const std::string &provider=ORCA_CLOUD_PROVIDER)
Definition GUI_App.cpp:6833

References check_privacy_update(), on_check_privacy_update(), on_show_check_privacy_dlg(), Slic3r::ORCA_CLOUD_PROVIDER(), and request_user_handle().

Referenced by on_check_privacy_update(), and on_init_inner().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_cloud_web_session_minted()

void Slic3r::GUI::GUI_App::on_cloud_web_session_minted ( const std::string & state,
uint64_t gen,
const std::string & token_hash )
6069{
6070 if (is_closing())
6071 return;
6072 // Drop a result for a superseded request (a newer request_web_session, login or sign-out).
6073 if (gen != m_cloud_handoff_gen || state != m_cloud_handoff_state)
6074 return;
6075 if (token_hash.empty())
6076 return;
6077
6078 auto orca = get_orca_cloud_agent(m_agent);
6079 if (!orca)
6080 return;
6081
6082 // Load the Complete URL in the SAME webview that posted request_web_session, because the
6083 // state lives in that webview's session storage (guide §3/§7).
6084 if (WebViewPanel* home = WebViewPanel::if_built())
6085 home->load_cloud_url(from_u8(orca->build_web_session_complete_url(token_hash, state)));
6086}
uint64_t m_cloud_handoff_gen
Definition GUI_App.hpp:373
std::string m_cloud_handoff_state
Definition GUI_App.hpp:370

References Slic3r::GUI::from_u8(), Slic3r::GUI::get_orca_cloud_agent(), Slic3r::GUI::LazyInstance< WebViewPanel >::if_built(), is_closing(), m_agent, m_cloud_handoff_gen, m_cloud_handoff_state, and on_cloud_web_session_minted().

Referenced by mint_cloud_web_session(), and on_cloud_web_session_minted().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_http_error()

void Slic3r::GUI::GUI_App::on_http_error ( wxCommandEvent & evt)
5808{
5809 int status = evt.GetInt();
5810 std::string provider = "";
5811 std::string body_str;
5812
5813 // Extract provider and body from event data
5814 try {
5815 auto evt_str = evt.GetString().utf8_string();
5816 if (!evt_str.empty()) {
5817 json evt_data = json::parse(evt_str);
5818 if (evt_data.contains("provider"))
5819 provider = evt_data["provider"].get<std::string>();
5820 if (evt_data.contains("body"))
5821 body_str = evt_data["body"].get<std::string>();
5822 }
5823 } catch (...) {}
5824
5825 int code = 0;
5826 std::string error;
5827 if (status >= 400 && status < 500) {
5828 try {
5829 if (!body_str.empty()) {
5830 json j = json::parse(body_str);
5831 if (j.contains("code")) {
5832 if (!j["code"].is_null())
5833 code = j["code"].get<int>();
5834 }
5835 if (j.contains("error"))
5836 if (!j["error"].is_null())
5837 error = j["error"].get<std::string>();
5838 }
5839 } catch (...) {}
5840 }
5841
5842 // Version limit
5843 if (code == HttpErrorVersionLimited) {
5844 MessageDialog msg_dlg(nullptr, _L("The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally."), "", wxAPPLY | wxOK);
5845 if (msg_dlg.ShowModal() == wxOK) {
5846 }
5847 }
5848
5849 // request login
5850 if (status == 401) {
5851 if (m_agent) {
5852 if (!provider.empty() && m_agent->is_user_login(provider)) {
5853 if (std::chrono::steady_clock::now() - m_last_401_error_time > 30s) {
5854 BOOST_LOG_TRIVIAL(warning) << "logout: http error 401.";
5855 // Involuntary: a 401 means the desktop session was rejected. Leave the
5856 // webview's own session alone (guide §8).
5857 this->request_user_logout(provider, /*user_initiated=*/false);
5858
5860 MessageDialog msg_dlg(nullptr, _L("Login information expired. Please login again."), "", wxAPPLY | wxOK);
5862 auto modal_result = msg_dlg.ShowModal();
5863 if (modal_result == wxOK || modal_result == wxCLOSE) {
5865 return;
5866 }
5867 }
5868
5869 m_last_401_error_time = std::chrono::steady_clock::now();
5870 } else {
5871 BOOST_LOG_TRIVIAL(warning) << "401 encountered within grace period, suppressing logout";
5872 }
5873 }
5874 }
5875 return;
5876 }
5877
5878 // No need to show dialog for 410: 410 means resource has been deleted from the server.
5879 if (status == 410) {
5880 BOOST_LOG_TRIVIAL(info) << "Http error 410.";
5881 return;
5882 }
5883
5884 if (status == 409 && provider == ORCA_CLOUD_PROVIDER) {
5885 BOOST_LOG_TRIVIAL(info) << "Http error 409.";
5886 // Parse the conflict body to extract the error code and server profile id
5887 int conflict_code = 0;
5888 std::string conflict_setting_id;
5889 std::string conflict_preset_name;
5890 try {
5891 json conflict_body = json::parse(body_str);
5892 if (conflict_body.contains("code"))
5893 conflict_code = conflict_body["code"].get<int>();
5894 if (conflict_body.contains("server_profile") && conflict_body["server_profile"].contains("id")
5895 && conflict_body["server_profile"]["id"].is_string())
5896 conflict_setting_id = conflict_body["server_profile"]["id"].get<std::string>();
5897 // The local preset name is injected into the conflict body by the agent (sync_push),
5898 // since the server response itself omits it for tombstone (-3) conflicts.
5899 if (conflict_body.contains("name") && conflict_body["name"].is_string())
5900 conflict_preset_name = conflict_body["name"].get<std::string>();
5901 } catch (...) {
5902 BOOST_LOG_TRIVIAL(warning) << "Failed to parse 409 conflict body.";
5903 }
5904 // Capture the user id up front so the force-push closure does not have to touch m_agent.
5905 std::string conflict_user_id = m_agent ? m_agent->get_user_id() : std::string();
5906 auto* plater = wxGetApp().plater();
5907 if (plater != nullptr && wxGetApp().imgui()->display_initialized()) {
5908 std::string text;
5909
5910 // Name the specific preset in the header so the user knows which one conflicts.
5911 // The agent injects the local preset name into every 409 conflict body, so this is
5912 // normally populated; fall back to a generic header if it is somehow missing.
5913 const std::string header = conflict_preset_name.empty()
5914 ? _u8L("Cloud sync conflict:")
5915 : format(_u8L("Cloud sync conflict for preset \"%s\":"), conflict_preset_name);
5916
5917 switch (conflict_code) {
5918 case -1:
5919 text = header + " " + _u8L("This preset has a newer version in OrcaCloud.\n"
5920 "Pull downloads the cloud copy. Force push overwrites it with your local preset.");
5921 break;
5922 case -2:
5923 text = header + " " + _u8L("A preset with this name already exists in OrcaCloud.\n"
5924 "Pull downloads the cloud copy. Force push overwrites it with your local preset.");
5925 break;
5926 case -3:
5927 text = header + " " + _u8L("A preset with the same name was previously deleted from the cloud.\n"
5928 "Delete will delete your local preset. Force push overwrites it with your local preset.");
5929 break;
5930 default:
5931 text = header + " " + _u8L("There was an unexpected or unidentified preset conflict.\n"
5932 "Pull downloads the cloud copy. Force push overwrites it with your local preset.");
5933 break;
5934 };
5935
5936 plater->get_notification_manager()->push_orca_sync_conflict_notification(
5937 text, conflict_code,
5938 [this](wxEvtHandler*) {
5939 // Runs on the GUI thread (on_http_error is a queued wx event); restart_sync_user_preset()
5940 // already joins the old sync thread off the UI thread, so no extra thread is needed here.
5941 if (is_closing() || !m_agent || !preset_bundle)
5942 return false;
5943 BOOST_LOG_TRIVIAL(info) << "Pulling Orca Cloud settings to resolve sync conflict.";
5945 return true;
5946 },
5947 [this, conflict_setting_id, conflict_preset_name, conflict_user_id](wxEvtHandler*) {
5948 if (mainframe == nullptr)
5949 return false;
5950 const wxString confirm_msg = conflict_preset_name.empty()
5951 ? _L("Force push will overwrite the cloud copy with your local preset changes.\nDo you want to continue?")
5952 : format_wxstr(_L("Force push will overwrite the cloud copy of preset \"%s\" with your local changes.\nDo you want to continue?"),
5953 conflict_preset_name);
5954 MessageDialog dlg(mainframe, confirm_msg, _L("Resolve cloud sync conflict"),
5955 wxCENTER | wxYES_NO | wxNO_DEFAULT | wxICON_WARNING);
5956 if (dlg.ShowModal() != wxID_YES)
5957 return false;
5958
5959 std::string setting_id = conflict_setting_id;
5960 if (setting_id.empty()) {
5961 setting_id = OrcaCloudServiceAgent::generate_uuid_for_setting_id(conflict_preset_name, conflict_user_id);
5962 BOOST_LOG_TRIVIAL(info) << "conflict setting id empty, generated one: " << setting_id;
5963 }
5964
5966 return true;
5967 });
5968 }
5969 return;
5970 }
5971
5972 // Show general error notification for Orca Cloud API failures (not Bambu)
5973 if (provider == ORCA_CLOUD_PROVIDER && status >= 400 && code != HttpErrorVersionLimited) {
5974 BOOST_LOG_TRIVIAL(warning) << "API call to OrcaCloud failed with status=" << status;
5975 }
5976}
bool m_show_http_error_msgdlg
Definition GUI_App.hpp:365
void restart_sync_user_preset()
Definition GUI_App.cpp:8235
void force_push_conflicting_preset(const std::string &setting_id)
Definition GUI_App.cpp:8274
ImGuiWrapper * imgui()
Definition GUI_App.hpp:816
@ HttpErrorVersionLimited
Definition Http.hpp:34
#define _u8L(s)
Definition I18N.hpp:11

References _L, _u8L, force_push_conflicting_preset(), Slic3r::GUI::format(), Slic3r::GUI::format_wxstr(), Slic3r::OrcaCloudServiceAgent::generate_uuid_for_setting_id(), Slic3r::HttpErrorVersionLimited, imgui(), is_closing(), m_agent, m_last_401_error_time, m_show_http_error_msgdlg, mainframe, on_http_error(), Slic3r::ORCA_CLOUD_PROVIDER(), plater(), preset_bundle, request_user_logout(), restart_sync_user_preset(), and Slic3r::GUI::DPIAware< P >::ShowModal().

Referenced by on_http_error(), and on_init_inner().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_init_inner()

bool Slic3r::GUI::GUI_App::on_init_inner ( )
private
3161{
3162 wxLog::SetActiveTarget(new wxBoostLog());
3163
3164#ifdef __APPLE__
3165 // Override wxWidgets' kAEGetURL handler so orcaslicer:// deep links keep
3166 // working after the wxWidgets 3.3.2 upgrade on macOS (#13119).
3168#endif
3169#if BBL_RELEASE_TO_PUBLIC
3170 wxLog::SetLogLevel(wxLOG_Message);
3171#endif
3172
3174
3175 // Register wxInspector plugins for Orca custom controls
3177
3178 // Set initialization of image handlers before any UI actions - See GH issue #7469
3179 wxInitAllImageHandlers();
3180#ifdef NDEBUG
3181 wxImage::SetDefaultLoadFlags(0); // ignore waring in release build
3182#endif
3183
3184#if defined(_WIN32) && ! defined(_WIN64)
3185 // BBS: remove 32bit build prompt
3186 // Win32 32bit build.
3187#endif // _WIN64
3188
3189 // Forcing back menu icons under gtk2 and gtk3. Solution is based on:
3190 // https://docs.gtk.org/gtk3/class.Settings.html
3191 // see also https://docs.wxwidgets.org/3.0/classwx_menu_item.html#a2b5d6bcb820b992b1e4709facbf6d4fb
3192 // TODO: Find workaround for GTK4
3193#if defined(__WXGTK20__) || defined(__WXGTK3__)
3194 g_object_set (gtk_settings_get_default (), "gtk-menu-images", TRUE, NULL);
3195#endif
3196
3197#if defined(__WXGTK20__) || defined(__WXGTK3__)
3198 // Suppress harmless GTK critical warnings from the GTK3/wxWidgets interaction.
3199 // These include widget allocation on hidden widgets, events on unrealized widgets,
3200 // and style context operations during widget construction (SetBackgroundColour
3201 // before GTK widget realization).
3202 g_log_set_handler("Gtk", G_LOG_LEVEL_CRITICAL,
3203 [](const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) {
3204 if (message && (strstr(message, "gtk_widget_set_allocation") ||
3205 strstr(message, "WIDGET_REALIZED_FOR_EVENT") ||
3206 strstr(message, "gtk_widget_get_style_context") ||
3207 strstr(message, "gtk_style_context_add_provider")))
3208 return;
3209 g_log_default_handler(log_domain, log_level, message, user_data);
3210 }, nullptr);
3211#endif
3212
3213#ifdef WIN32
3214 //BBS set crash log folder
3216#endif
3217
3218 wxGetApp().Bind(wxEVT_QUERY_END_SESSION, [this](auto & e) {
3219 BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< "received wxEVT_QUERY_END_SESSION";
3220 if (mainframe) {
3221 wxCloseEvent e2(wxEVT_CLOSE_WINDOW);
3222 e2.SetCanVeto(true);
3223 mainframe->GetEventHandler()->ProcessEvent(e2);
3224 if (e2.GetVeto()) {
3225 e.Veto();
3226 return;
3227 }
3228 }
3229 for (auto d : dialogStack)
3230 d->EndModal(wxID_ABORT);
3231 });
3232
3233#ifdef __APPLE__
3234 // A quit request from the Dock, a logout or a restart ends with AppKit calling exit() right after this event, so
3235 // OnExit() and ~GUI_App() never run. Shut the plugins and Python down here as ~GUI_App() does. Left to
3236 // PluginManager's static destructor, the shutdown locks hook state that has already been destroyed and aborts.
3237 // Unload the Bambu network plugin too. Its static destructors abort if its agent's threads are still running.
3238 // Stop the Orca Cloud health check as OnExit() does, so no request is in flight while exit() tears down.
3239 wxGetApp().Bind(wxEVT_END_SESSION, [this](wxCloseEvent &e) {
3240 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "received wxEVT_END_SESSION";
3246 e.Skip();
3247 });
3248#endif
3249
3250 // Verify resources path
3251 const wxString resources_dir = from_u8(Slic3r::resources_dir());
3252 wxCHECK_MSG(wxDirExists(resources_dir), false,
3253 wxString::Format(_L("Resources path does not exist or is not a directory: %s"), resources_dir));
3254
3255#ifdef __linux__
3256 if (! check_old_linux_datadir(GetAppName())) {
3257 std::cerr << "Quitting, user chose to move their data to new location." << std::endl;
3258 return false;
3259 }
3260#endif
3261
3262 BOOST_LOG_TRIVIAL(info) << get_system_info();
3263
3264// initialize label colors and fonts
3266 init_fonts();
3267 wxGetApp().Update_dark_mode_flag();
3268
3269#if defined(__WINDOWS__)
3270 HMODULE hKernel32 = GetModuleHandleW(L"kernel32.dll");
3271 m_is_arm64 = false;
3272 if (hKernel32) {
3273 auto fnIsWow64Process2 = (LPFN_ISWOW64PROCESS2)GetProcAddress(hKernel32, "IsWow64Process2");
3274 if (fnIsWow64Process2) {
3275 USHORT processMachine = 0;
3276 USHORT nativeMachine = 0;
3277 if (fnIsWow64Process2(GetCurrentProcess(), &processMachine, &nativeMachine)) {
3278 if (nativeMachine == IMAGE_FILE_MACHINE_ARM64) {//IMAGE_FILE_MACHINE_ARM64
3279 m_is_arm64 = true;
3280 }
3281 BOOST_LOG_TRIVIAL(info) << boost::format("processMachine architecture %1%, nativeMachine %2% m_is_arm64 %3%")%(int)(processMachine) %(int) nativeMachine %m_is_arm64;
3282 }
3283 else {
3284 BOOST_LOG_TRIVIAL(info) << boost::format("IsWow64Process2 failed, set m_is_arm64 to %1%") %m_is_arm64;
3285 }
3286 }
3287 else {
3288 BOOST_LOG_TRIVIAL(info) << boost::format("can not find IsWow64Process2, set m_is_arm64 to %1%") %m_is_arm64;
3289 }
3290 }
3291 else {
3292 BOOST_LOG_TRIVIAL(info) << boost::format("can not find kernel32, set m_is_arm64 to %1%") %m_is_arm64;
3293 }
3294#endif
3295 // Enable this to get the default Win32 COMCTRL32 behavior of static boxes.
3296// wxSystemOptions::SetOption("msw.staticbox.optimized-paint", 0);
3297 // Enable this to disable Windows Vista themes for all wxNotebooks. The themes seem to lead to terrible
3298 // performance when working on high resolution multi-display setups.
3299// wxSystemOptions::SetOption("msw.notebook.themed-background", 0);
3300
3301// Slic3r::debugf "wxWidgets version %s, Wx version %s\n", wxVERSION_STRING, wxVERSION;
3302 if (is_editor()) {
3303 std::string msg = Slic3r::Http::tls_global_init();
3304 std::string ssl_cert_store = app_config->get("tls_accepted_cert_store_location");
3305 bool ssl_accept = app_config->get("tls_cert_store_accepted") == "yes" && ssl_cert_store == Slic3r::Http::tls_system_cert_store();
3306
3307 if (!msg.empty() && !ssl_accept) {
3308 RichMessageDialog
3309 dlg(nullptr,
3310 wxString::Format(_L("%s\nDo you want to continue?"), msg),
3311 "OrcaSlicer", wxICON_QUESTION | wxYES_NO);
3312 dlg.ShowCheckBox(_L("Remember my choice"));
3313 if (dlg.ShowModal() != wxID_YES) return false;
3314
3315 app_config->set("tls_cert_store_accepted",
3316 dlg.IsCheckBoxChecked() ? "yes" : "no");
3317 app_config->set("tls_accepted_cert_store_location",
3318 dlg.IsCheckBoxChecked() ? Slic3r::Http::tls_system_cert_store() : "");
3319 }
3320 }
3321
3322 // !!! Initialization of UI settings as a language, application color mode, fonts... have to be done before first UI action.
3323 // Like here, before the show InfoDialog in check_older_app_config()
3324
3325 // If load_language() fails, the application closes.
3326 load_language(wxString(), true);
3327#ifdef _MSW_DARK_MODE
3328
3329#ifndef __WINDOWS__
3330 // The label colours and the dark mode flag were set above from the saved mode. When the system theme
3331 // differs from it, refresh them, or dialogs that map their colours stay in the old mode for this session.
3332 const bool saved_dark_mode = dark_mode();
3333 wxSystemAppearance app = wxSystemSettings::GetAppearance();
3334 GUI::wxGetApp().app_config->set("dark_color_mode", app.IsDark() ? "1" : "0");
3335 GUI::wxGetApp().app_config->save();
3336 if (dark_mode() != saved_dark_mode) {
3339 }
3340#endif // __APPLE__
3341
3342
3343 bool init_dark_color_mode = dark_mode();
3344 bool init_sys_menu_enabled = app_config->get("sys_menu_enabled") == "1";
3345#ifdef __WINDOWS__
3346 // Inform wxWidgets 3.3's dark mode system so it tracks NppDarkMode's state.
3347 // Must be called before NppDarkMode::InitDarkMode() so that NppDarkMode's
3348 // SetPreferredAppMode(ForceDark) overrides the AllowDark state set here.
3349 // Orca: todo switch to native dark mode support in wxWidgets and remove NppDarkMode
3350 MSWEnableDarkMode(DarkMode_Auto);
3351 NppDarkMode::InitDarkMode(init_dark_color_mode, init_sys_menu_enabled);
3352#endif // __WINDOWS__
3353
3354#endif
3355
3356
3357#ifdef _MSW_DARK_MODE
3358 // app_config can be updated in check_older_app_config(), so check if dark_color_mode and sys_menu_enabled was changed
3359 if (bool new_dark_color_mode = dark_mode();
3360 init_dark_color_mode != new_dark_color_mode) {
3361
3362#ifdef __WINDOWS__
3363 NppDarkMode::SetDarkMode(new_dark_color_mode);
3364#endif // __WINDOWS__
3365
3367 //update_label_colours_from_appconfig();
3368 }
3369 if (bool new_sys_menu_enabled = app_config->get("sys_menu_enabled") == "1";
3370 init_sys_menu_enabled != new_sys_menu_enabled) {
3371#ifdef __WINDOWS__
3372 NppDarkMode::SetSystemMenuForApp(new_sys_menu_enabled);
3373#endif
3374 }
3375#endif
3376
3377 // Orca: we allow user to pin the version of plugin, so we don't need to remove old networking plugins when the app version is updated
3378 //
3379 // if (m_last_config_version) {
3380 // int last_major = m_last_config_version->maj();
3381 // int last_minor = m_last_config_version->min();
3382 // int last_patch = m_last_config_version->patch()/100;
3383 // std::string studio_ver = SLIC3R_VERSION;
3384 // int cur_major = atoi(studio_ver.substr(0,2).c_str());
3385 // int cur_minor = atoi(studio_ver.substr(3,2).c_str());
3386 // int cur_patch = atoi(studio_ver.substr(6,2).c_str());
3387 // BOOST_LOG_TRIVIAL(info) << boost::format("last app version {%1%.%2%.%3%}, current version {%4%.%5%.%6%}")
3388 // %last_major%last_minor%last_patch%cur_major%cur_minor%cur_patch;
3389 // if ((last_major != cur_major)
3390 // ||(last_minor != cur_minor)
3391 // ||(last_patch != cur_patch)) {
3392 // remove_old_networking_plugins();
3393 // }
3394 // }
3395
3396 //Orca: write OrcaSlicer version
3397 if(app_config->get("version") != SoftFever_VERSION) {
3398 app_config->set("version", SoftFever_VERSION);
3399 }
3400
3401 // Orca: use wxWeakRef to provent wild pointer.
3402 wxWeakRef<SplashScreen> scrn = nullptr;
3403 if (app_config->get("show_splash_screen") == "true") {
3404 // Detect position (display) to show the splash screen
3405 // Now this position is equal to the mainframe position
3406 wxPoint splashscreen_pos = wxDefaultPosition;
3407 if (app_config->has("window_mainframe")) {
3408 auto metrics = WindowMetrics::deserialize(app_config->get("window_mainframe"));
3409 if (metrics)
3410 splashscreen_pos = metrics->get_rect().GetPosition();
3411 }
3412
3413 BOOST_LOG_TRIVIAL(info) << "begin to show the splash screen...";
3414 //BBS use BBL splashScreen
3415 scrn = new SplashScreen(splashscreen_pos);
3416 wxYield();
3417 scrn->SetText(_L("Loading configuration") + dots, 5);
3418 }
3419
3420 BOOST_LOG_TRIVIAL(info) << "loading systen presets...";
3421 preset_bundle = new PresetBundle();
3422
3423 // just checking for existence of Slic3r::data_dir is not enough : it may be an empty directory
3424 // supplied as argument to --datadir; in that case we should still run the wizard
3425 preset_bundle->setup_directories();
3426
3427
3430
3431 if (is_editor()) {
3432#ifdef __WXMSW__
3433 if (app_config->get("associate_3mf") == "true")
3434 associate_files(L"3mf");
3435 if (app_config->get("associate_stl") == "true")
3436 associate_files(L"stl");
3437 if (app_config->get("associate_step") == "true") {
3438 associate_files(L"step");
3439 associate_files(L"stp");
3440 }
3441 associate_url(L"orcaslicer");
3442
3443 if (app_config->get("associate_gcode") == "true")
3444 associate_files(L"gcode");
3445#endif // __WXMSW__
3446
3447 preset_updater = new PresetUpdater();
3448 Bind(EVT_SLIC3R_VERSION_ONLINE, [this](const wxCommandEvent& evt) {
3449 if (this->plater_ != nullptr) {
3450 // this->plater_->get_notification_manager()->push_notification(NotificationType::NewAppAvailable);
3451 //BBS show msg box to download new version
3452 /* wxString tips = wxString::Format(_L("Click to download new version in default browser: %s"), version_info.version_str);
3453 DownloadDialog dialog(this->mainframe,
3454 tips,
3455 _L("New version of Orca Slicer"),
3456 false,
3457 wxCENTER | wxICON_INFORMATION);
3458
3459
3460 dialog.SetExtendedMessage(extmsg);*/
3461 std::string skip_version_str = this->app_config->get("app", "skip_version");
3462 bool skip_this_version = false;
3463 if (!skip_version_str.empty()) {
3464 BOOST_LOG_TRIVIAL(info) << "new version = " << version_info.version_str << ", skip version = " << skip_version_str;
3465 if (version_info.version_str <= skip_version_str) {
3466 skip_this_version = true;
3467 } else {
3468 app_config->set("skip_version", "");
3469 skip_this_version = false;
3470 }
3471 }
3472 if (!skip_this_version
3473 || evt.GetInt() != 0) {
3474 UpdateVersionDialog dialog(this->mainframe);
3475 wxString extmsg = wxString::FromUTF8(version_info.description);
3476 dialog.update_version_info(extmsg, version_info.version_str);
3477 //dialog.update_version_info(version_info.description);
3478 if (evt.GetInt() != 0) {
3479 dialog.m_button_skip_version->Hide();
3480 }
3481 switch (dialog.ShowModal())
3482 {
3483 case wxID_YES:
3484 // Store builds get updates from the Microsoft Store, not the GitHub release page.
3485 if (is_running_in_msix())
3487 else
3488 wxLaunchDefaultBrowser(version_info.url);
3489 break;
3490 case wxID_NO:
3491 break;
3492 default:
3493 ;
3494 }
3495 }
3496 }
3497 });
3498
3499 Bind(EVT_ENTER_FORCE_UPGRADE, [this](const wxCommandEvent& evt) {
3500 wxString version_str = wxString::FromUTF8(this->app_config->get("upgrade", "version"));
3501 wxString description_text = wxString::FromUTF8(this->app_config->get("upgrade", "description"));
3502 std::string download_url = this->app_config->get("upgrade", "url");
3503 wxString tips = wxString::Format(_L("Click to download new version in default browser: %s"), version_str);
3504 DownloadDialog dialog(this->mainframe,
3505 tips,
3506 _L("OrcaSlicer needs an update"),
3507 false,
3508 wxCENTER | wxICON_INFORMATION);
3509 dialog.SetExtendedMessage(description_text);
3510
3511 int result = dialog.ShowModal();
3512 switch (result)
3513 {
3514 case wxID_YES:
3515 wxLaunchDefaultBrowser(download_url);
3516 break;
3517 case wxID_NO:
3518 wxGetApp().mainframe->Close(true);
3519 break;
3520 default:
3521 wxGetApp().mainframe->Close(true);
3522 }
3523 });
3524
3525 Bind(EVT_SHOW_NO_NEW_VERSION, [](const wxCommandEvent& evt) {
3526 wxString msg = _L("This is the newest version.");
3527 InfoDialog dlg(nullptr, _L("Info"), msg);
3528 dlg.ShowModal();
3529 });
3530
3531 Bind(EVT_SHOW_DIALOG, [this](const wxCommandEvent& evt) {
3532 wxString msg = evt.GetString();
3533 InfoDialog dlg(this->mainframe, _L("Info"), msg);
3534 dlg.Bind(wxEVT_DESTROY, [this](auto& e) {
3535 m_info_dialog_content = wxEmptyString;
3536 });
3537 dlg.ShowModal();
3538 });
3539 }
3540 else {
3541#ifdef __WXMSW__
3542 if (app_config->get("associate_gcode") == "true")
3543 associate_files(L"gcode");
3544#endif // __WXMSW__
3545 }
3546
3547 // Suppress the '- default -' presets.
3548 preset_bundle->set_default_suppressed(true);
3549
3550 preset_bundle->backup_user_folder();
3551
3552 Bind(EVT_UPDATE_MACHINE_LIST, &GUI_App::on_update_machine_list, this);
3553 Bind(EVT_USER_LOGIN, &GUI_App::on_user_login, this);
3554 Bind(EVT_USER_LOGIN_HANDLE, &GUI_App::on_user_login_handle, this);
3555 Bind(EVT_CHECK_PRIVACY_VER, &GUI_App::on_check_privacy_update, this);
3556 Bind(EVT_CHECK_PRIVACY_SHOW, &GUI_App::show_check_privacy_dlg, this);
3557
3558 Bind(EVT_SHOW_IP_DIALOG, &GUI_App::show_ip_address_enter_dialog_handler, this);
3559
3560
3561
3562 // Orca: select network plugin version based on configured version string
3563 std::string configured_version = app_config->get_network_plugin_version();
3564 BOOST_LOG_TRIVIAL(info) << "Network plugin mode: "
3565 << (use_legacy_network_plugin() ? ("legacy (version: " + std::string(BAMBU_NETWORK_AGENT_VERSION_LEGACY) + ")") : ("modern (version: " + configured_version + ")"));
3566 // Force legacy network plugin if debugger attached
3567 // See https://github.com/bambulab/BambuStudio/issues/6726
3568 /* if (!NetworkAgent::use_legacy_network) {
3569 bool debugger_attached = false;
3570#if defined(__WINDOWS__)
3571 debugger_attached = IsDebuggerPresent();
3572#elif defined(__WXOSX__) || defined(__linux__)
3573 debugger_attached = is_debugger_present();
3574#endif
3575 if (debugger_attached) {
3576 NetworkAgent::use_legacy_network = true;
3577 wxMessageBox("Force using legacy bambu networking plugin because debugger is attached! If the app terminates itself immediately, please delete installed plugin and try again!");
3578 }
3579 } */
3580
3581
3582 if (scrn) {
3583 scrn->SetText(_L("Loading Plugins") + dots, 20);
3584 wxYield();
3585 }
3586
3587 // Initialize plugins after network then register on_load callbacks so once the plugin loads finish, it gets registered automatically.
3588 // initialize() also installs the libslic3r hooks (capability resolver,
3589 // slicing-pipeline dispatcher) via plugin_hooks::install() -- no
3590 // per-capability wiring belongs here.
3591 PluginManager& plugin_mgr = PluginManager::instance();
3592 plugin_mgr.initialize();
3593
3594 // Set cloud plugin directory from previous session so cloud-installed
3595 // plugins are discovered even before the network agent is ready.
3596 const std::string preset_folder = app_config->get("preset_folder");
3597 if (!preset_folder.empty()) {
3598 plugin_mgr.set_cloud_user(preset_folder);
3599 }
3600
3601 plugin_mgr.discover_plugins(false, true);
3602
3604
3605 // Subscribe to the plugin loader and enumerate current actions (UI thread, once).
3606 m_action_registry.init();
3607
3608 for (const std::string& plugin_key : plugin_mgr.get_enabled_plugin_keys()) {
3609 if (!plugin_mgr.is_plugin_loaded(plugin_key)) {
3610 plugin_mgr.load_plugin(plugin_key, false);
3611 BOOST_LOG_TRIVIAL(info) << "Auto-loading plugin on startup: " << plugin_key;
3612 }
3613 }
3614
3617
3618 if (m_agent)
3619 plugin_mgr.set_cloud_agent(std::dynamic_pointer_cast<OrcaCloudServiceAgent>(m_agent->get_cloud_agent()));
3620
3621 if (m_agent && m_agent->is_user_login()) {
3623 plugin_mgr.set_cloud_user(m_agent->get_user_id());
3624 // If there is a user logged in we do an immediate sync.
3625 std::vector<std::string> not_found, unauthorized;
3626 plugin_mgr.fetch_plugins_from_cloud(&not_found, &unauthorized);
3627 if (plater()) {
3628 for (const auto& uuid : not_found) {
3632 format(_L("Plugin %s is no longer available."), uuid));
3633 }
3634 for (const auto& uuid : unauthorized) {
3638 format(_L("Plugin %s access is unauthorized."), uuid));
3639 }
3640 }
3641 } else {
3643 plugin_mgr.set_cloud_user("");
3644 }
3645
3646 // BBS if load user preset failed
3647 // Let the libslic3r know the callback, which will translate messages on demand.
3648 // Installed before the presets load so that their load errors are translated too.
3650
3651 //if (loaded_preset_result != 0) {
3652 try {
3653 // Enable all substitutions (in both user and system profiles), but log the substitutions in user profiles only.
3654 // If there are substitutions in system profiles, then a "reconfigure" event shall be triggered, which will force
3655 // installation of a compatible system preset, thus nullifying the system preset substitutions.
3656 if (scrn) { scrn->SetText(_L("Loading printer & filament profiles") + dots, 30); wxYield(); }
3658 }
3659 catch (const std::exception& ex) {
3660 show_error(nullptr, ex.what());
3661 }
3662 //}
3663
3664#ifdef WIN32
3665 register_win32_device_notification_event();
3666#endif // WIN32
3667
3668#if defined(__WXGTK__) && wxHAS_EGL
3669 // Configure GL backend before any wxGLCanvas is created.
3670 // On X11, prefer GLX for maximum driver compatibility.
3671 // On Wayland, EGL is used by default (only option).
3672 if (Slic3r::GUI::is_running_on_x11()) {
3673 wxGLCanvas::PreferGLX();
3674 BOOST_LOG_TRIVIAL(info) << "X11 detected, using GLX for OpenGL context";
3675 } else if (Slic3r::GUI::is_running_on_wayland()) {
3676 BOOST_LOG_TRIVIAL(info) << "Wayland detected, using EGL for OpenGL context";
3677 } else {
3678 BOOST_LOG_TRIVIAL(warning) << "Unknown display backend, defaulting to EGL";
3679 }
3680#endif
3681
3682 if (scrn) {
3683 const auto scrn_txt = _L("Creating main window") + dots;
3684 scrn->SetText(scrn_txt, 70);
3685 wxYield();
3686 }
3687 BOOST_LOG_TRIVIAL(info) << "create the main window";
3688 mainframe = new MainFrame();
3689 // The first render can happen as soon as the frame is shown, before the queued
3690 // new_project() sets the same view.
3691 plater_->get_camera().select_view("topfront");
3692 plater_->get_camera().requires_zoom_to_bed = true;
3693 if (is_editor()) {
3694 if (starts_on_prepare()) {
3695 mainframe->select_tab(TAB_ID_PREPARE);
3696 } else {
3697 mainframe->select_tab(TAB_ID_HOME);
3698 }
3699 }
3700
3701 sidebar().obj_list()->init();
3702 //sidebar().aux_list()->init_auxiliary();
3703
3704// update_mode(); // !!! do that later
3705 SetTopWindow(mainframe);
3706
3707 plater_->init_notification_manager();
3708
3709 m_printhost_job_queue.reset(new PrintHostJobQueue(mainframe->printhost_queue_dlg()));
3710
3711 if (is_gcode_viewer()) {
3712 mainframe->update_layout();
3713 if (plater_ != nullptr)
3714 // ensure the selected technology is ptFFF
3715 plater_->set_printer_technology(ptFFF);
3716 }
3717 else {
3718 if (scrn) { scrn->SetText(_L("Loading current preset") + dots, 85); wxYield(); }
3720 }
3721
3722 if (plater_ != nullptr) {
3723 plater_->reset_project_dirty_initial_presets();
3724 plater_->update_project_dirty_from_presets();
3725 plater_->get_partplate_list().set_filament_count(preset_bundle->filament_presets.size());
3726 }
3727
3728 // BBS:
3729#ifdef __WINDOWS__
3730 mainframe->topbar()->SaveNormalRect();
3731#endif
3732 if (scrn) { scrn->SetText(_L("Showing main window") + dots, 95); wxYield(); }
3733 mainframe->Show(true);
3734 // Close the splash now that the main UI is visible.
3735 if (scrn) { scrn->SetText(_L("Showing main window") + dots, 100); scrn->Destroy(); scrn = nullptr; }
3736 BOOST_LOG_TRIVIAL(info) << "main frame firstly shown";
3737
3738//#if BBL_HAS_FIRST_PAGE
3739 //BBS: set tp3DEditor firstly
3740 /*plater_->canvas3D()->enable_render(false);
3741 mainframe->select_tab(size_t(MainFrame::tp3DEditor));
3742 scrn->SetText(_L("Loading Opengl resourses..."));
3743 plater_->select_view_3D("3D");
3744 //BBS init the opengl resource here
3745 Size canvas_size = plater_->canvas3D()->get_canvas_size();
3746 wxGetApp().imgui()->set_display_size(static_cast<float>(canvas_size.get_width()), static_cast<float>(canvas_size.get_height()));
3747 wxGetApp().init_opengl();
3748 plater_->canvas3D()->init();
3749 wxGetApp().imgui()->new_frame();
3750 plater_->canvas3D()->enable_render(true);
3751 plater_->canvas3D()->render();
3752 if (is_editor())
3753 mainframe->select_tab(size_t(0));*/
3754//#else
3755 //plater_->trigger_restore_project(1);
3756//#endif
3757
3759
3760 update_mode(); // update view mode after fix of the object_list size
3761
3762#ifdef __APPLE__
3763 other_instance_message_handler()->bring_instance_forward();
3764#endif //__APPLE__
3765
3766 Bind(EVT_HTTP_ERROR, &GUI_App::on_http_error, this);
3767
3768
3769 Bind(wxEVT_IDLE, [this](wxIdleEvent& event)
3770 {
3771 bool curr_studio_active = this->is_studio_active();
3772 if (m_studio_active != curr_studio_active) {
3773 if (curr_studio_active) {
3774 BOOST_LOG_TRIVIAL(info) << "studio is active, start to subscribe";
3775 if (m_agent) {
3776 json j = json::object();
3777 m_agent->start_subscribe("app");
3778 }
3779 } else {
3780 BOOST_LOG_TRIVIAL(info) << "studio is inactive, stop to subscribe";
3781 if (m_agent) {
3782 json j = json::object();
3783 m_agent->stop_subscribe("app");
3784 }
3785 }
3786 m_studio_active = curr_studio_active;
3787 }
3788
3789
3790 if (! plater_)
3791 return;
3792
3793 // BBS
3794 //this->obj_manipul()->update_if_dirty();
3795
3796 //use m_post_initialized instead
3797 //static bool update_gui_after_init = true;
3798
3799 // An ugly solution to GH #5537 in which GUI_App::init_opengl (normally called from events wxEVT_PAINT
3800 // and wxEVT_SET_FOCUS before GUI_App::post_init is called) wasn't called before GUI_App::post_init and OpenGL wasn't initialized.
3801//#ifdef __linux__
3802// if (!m_post_initialized && m_opengl_initialized) {
3803//#else
3805//#endif
3806 m_post_initialized = true;
3807#ifdef WIN32
3808 this->mainframe->register_win32_callbacks();
3809#endif
3810 this->post_init();
3811
3813 }
3814
3815 if (m_post_initialized && app_config->dirty() && app_config->save_due())
3816 app_config->save();
3817
3818 });
3819
3820 m_initialized = true;
3821
3822 flush_logs();
3823
3824 BOOST_LOG_TRIVIAL(info) << "finished the gui app init";
3825 if (m_config_corrupted) {
3826 m_config_corrupted = false;
3827 show_error(nullptr,
3828 _u8L(
3829 "The OrcaSlicer configuration file may be corrupted and cannot be parsed.\nOrcaSlicer has attempted to recreate the "
3830 "configuration file.\nPlease note, application settings will be lost, but printer profiles will not be affected."));
3831 }
3832 return true;
3833}
#define TAB_ID_HOME
Definition MainFrame.hpp:56
void RegisterOrcaInspectorPlugins()
Definition Registration.hpp:8
static void set_log_folder(std::string log_folder)
Definition BaseException.cpp:65
static void initSysFont()
Definition Label.cpp:101
void on_update_machine_list(wxCommandEvent &evt)
Definition GUI_App.cpp:5993
void on_user_login(wxCommandEvent &evt)
Definition GUI_App.cpp:6165
bool load_language(wxString language, bool initial)
Definition GUI_App.cpp:8462
bool is_studio_active()
Definition GUI_App.cpp:6177
void init_fonts()
Definition GUI_App.cpp:4748
void on_check_privacy_update(wxCommandEvent &evt)
Definition GUI_App.cpp:6859
void show_check_privacy_dlg(wxCommandEvent &evt)
Definition GUI_App.cpp:6809
void copy_older_config()
Definition GUI_App.cpp:2844
void init_plugin_gui_wiring()
Definition GUI_App.cpp:3017
ObjectList * obj_list()
Definition GUI_App.cpp:9699
std::unique_ptr< PrintHostJobQueue > m_printhost_job_queue
Definition GUI_App.hpp:314
bool m_studio_active
Definition GUI_App.hpp:598
void on_http_error(wxCommandEvent &evt)
Definition GUI_App.cpp:5807
bool starts_on_prepare() const
Definition GUI_App.cpp:8734
void stop_sync_user_preset()
Definition GUI_App.cpp:8221
void Update_dark_mode_flag()
Definition GUI_App.cpp:4686
bool is_gcode_viewer() const
Definition GUI_App.hpp:427
void init_label_colours()
Definition GUI_App.cpp:4492
bool on_init_network(bool try_backup=false)
Definition GUI_App.cpp:3973
void post_init()
Definition GUI_App.cpp:936
bool m_init_app_config_from_older
Definition GUI_App.hpp:908
OtherInstanceMessageHandler * other_instance_message_handler()
Definition GUI_App.hpp:808
void enable_user_preset_folder(bool enable)
Definition GUI_App.cpp:5978
void update_publish_status()
Definition GUI_App.cpp:4527
void associate_files(std::wstring extend)
Definition GUI_App.cpp:10312
void copy_network_if_available()
Definition GUI_App.cpp:3835
bool m_post_initialized
Definition GUI_App.hpp:267
void show_ip_address_enter_dialog_handler(wxCommandEvent &evt)
Definition GUI_App.cpp:8876
void on_user_login_handle(wxCommandEvent &evt)
Definition GUI_App.cpp:6088
void associate_url(std::wstring url_prefix)
Definition GUI_App.cpp:10394
void push_notification(const NotificationType type, int timestamp=0)
Definition NotificationManager.cpp:1892
void init()
Definition GUI_ObjectList.cpp:4880
void set_min_height()
Definition GUI_ObjectList.cpp:367
const NotificationManager * get_notification_manager() const
Definition Plater.cpp:23864
static boost::optional< WindowMetrics > deserialize(const std::string &str)
Definition GUI_Utils.cpp:407
static std::string tls_global_init()
Definition Http.cpp:951
static std::string tls_system_cert_store()
Definition Http.cpp:959
void InitDarkMode(bool set_dark_mode, bool set_sys_menu)
Definition dark_mode.cpp:306
void SetSystemMenuForApp(bool set_sys_menu)
Definition dark_mode.cpp:326
static wxString dots("...", wxConvUTF8)
static std::string libslic3r_translate_callback(const char *s)
Definition GUI_App.cpp:747
std::string get_system_info()
Definition GUI_App.cpp:2989
std::deque< wxDialog * > dialogStack
Definition GUI_Utils.cpp:549
void open_ms_store_product_page()
Definition GUI_Utils.cpp:215
void register_mac_deep_link_handler()
Definition DeepLinkHandlerMac.mm:27
void set_translate_callback(translate_fn_type fn)
Definition I18N.hpp:17
@ EnableSystemSilent
Definition Config.hpp:249
void flush_logs()
Definition utils.cpp:480

References _L, _u8L, app_config, associate_files(), associate_url(), BAMBU_NETWORK_AGENT_VERSION_LEGACY, copy_network_if_available(), copy_older_config(), Slic3r::GUI::CustomNotification, dark_mode(), Slic3r::data_dir(), Slic3r::GUI::WindowMetrics::deserialize(), Slic3r::GUI::dialogStack, Slic3r::PluginManager::discover_plugins(), Slic3r::GUI::dots(), enable_user_preset_folder(), Slic3r::EnableSystemSilent, Slic3r::PluginManager::fetch_plugins_from_cloud(), Slic3r::flush_logs(), Slic3r::GUI::format(), Slic3r::GUI::from_u8(), Slic3r::PluginManager::get_enabled_plugin_keys(), Slic3r::GUI::get_system_info(), init_fonts(), init_label_colours(), init_params, init_plugin_gui_wiring(), NppDarkMode::InitDarkMode(), Slic3r::PluginManager::initialize(), Label::initSysFont(), Slic3r::PluginManager::instance(), Slic3r::PythonInterpreter::instance(), is_editor(), is_gcode_viewer(), Slic3r::PluginManager::is_plugin_loaded(), Slic3r::GUI::is_running_in_msix(), is_studio_active(), Slic3r::GUI::RichMessageDialog::IsCheckBoxChecked(), L, Slic3r::GUI::libslic3r_translate_callback(), load_current_presets(), load_language(), Slic3r::PluginManager::load_plugin(), m_action_registry, m_adding_script_handler, m_agent, Slic3r::GUI::UpdateVersionDialog::m_button_skip_version, m_config_corrupted, m_info_dialog_content, m_init_app_config_from_older, m_initialized, m_post_initialized, m_printhost_job_queue, m_studio_active, mainframe, obj_list(), on_check_privacy_update(), on_http_error(), on_init_inner(), on_init_network(), on_update_machine_list(), on_user_login(), on_user_login_handle(), Slic3r::GUI::open_ms_store_product_page(), other_instance_message_handler(), plater(), plater_, post_init(), preset_bundle, preset_updater, Slic3r::ptFFF, Slic3r::GUI::register_mac_deep_link_handler(), RegisterOrcaInspectorPlugins(), Slic3r::GUI::NotificationManager::RegularNotificationLevel, Slic3r::resources_dir(), Slic3r::PluginManager::set_cloud_agent(), Slic3r::PluginManager::set_cloud_user(), CBaseException::set_log_folder(), Slic3r::I18N::set_translate_callback(), NppDarkMode::SetDarkMode(), Slic3r::GUI::DownloadDialog::SetExtendedMessage(), NppDarkMode::SetSystemMenuForApp(), show_check_privacy_dlg(), Slic3r::GUI::show_error(), show_ip_address_enter_dialog_handler(), Slic3r::GUI::RichMessageDialog::ShowCheckBox(), Slic3r::GUI::DPIAware< P >::ShowModal(), Slic3r::GUI::RichMessageDialog::ShowModal(), Slic3r::PluginManager::shutdown(), Slic3r::PythonInterpreter::shutdown(), sidebar(), starts_on_prepare(), stop_sync_user_preset(), TAB_ID_HOME, TAB_ID_PREPARE, Slic3r::Http::tls_global_init(), Slic3r::Http::tls_system_cert_store(), Slic3r::NetworkAgent::unload_network_module(), Update_dark_mode_flag(), update_mode(), update_publish_status(), Slic3r::GUI::UpdateVersionDialog::update_version_info(), use_legacy_network_plugin(), and version_info.

Referenced by on_init_inner(), and OnInit().

Here is the caller graph for this function:

◆ on_init_network()

bool Slic3r::GUI::GUI_App::on_init_network ( bool try_backup = false)
private
3974{
3975 // Clean up stale ".old" files left by install_plugin() when it had to rename an in-use
3976 // DLL aside (see the rename-aside path in install_plugin). This runs before the plug-in
3977 // is (re)loaded - at startup nothing is mapped yet, and on a hot reload the previous
3978 // module has already been unloaded - so the previously locked files can now be removed.
3979 {
3980 boost::filesystem::path plugin_folder = boost::filesystem::path(data_dir()) / "plugins";
3981 boost::system::error_code ec;
3982 if (boost::filesystem::is_directory(plugin_folder, ec)) {
3983 for (boost::filesystem::directory_iterator it(plugin_folder, ec), end; !ec && it != end; it.increment(ec)) {
3984 if (it->path().extension() == ".old") {
3985 boost::system::error_code rm_ec;
3986 boost::filesystem::remove(it->path(), rm_ec);
3987 if (rm_ec)
3988 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": could not remove stale " << it->path().filename().string()
3989 << " (" << rm_ec.message() << "), will retry next launch";
3990 }
3991 }
3992 }
3993 }
3994
3995 auto should_load_networking_plugin = app_config->get_bool("installed_networking");
3996
3997 // Normalize an older full-version identity to the AA.BB.CC series before it drives loading.
3999
4000 std::string config_version = app_config->get_network_plugin_version();
4001
4002 if (should_load_networking_plugin) {
4003 // A version outside the whitelisted series (e.g. 02.03.00.62 configured by an older
4004 // Orca release) must not be loaded - its ABI no longer matches this build. Fall back
4005 // to the latest supported build if it is already on disk; otherwise clear the
4006 // configured version so the normal empty-version download flow takes over (the
4007 // download URL and install adoption both derive from the configured version, so it
4008 // must not keep pointing at the unsupported build).
4009 if (!config_version.empty() && !is_supported_network_version(config_version)) {
4010 std::string latest = get_latest_network_version();
4011 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": configured plugin version " << config_version
4012 << " is no longer supported, falling back to " << latest;
4013 config_version = BBLNetworkPlugin::versioned_library_exists(latest) ? latest : "";
4014 app_config->set_network_plugin_version(config_version);
4015 app_config->save();
4016 }
4017
4018 if (config_version.empty()) {
4019 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": no version configured, need to download";
4021 } else {
4022 int load_agent_dll = Slic3r::NetworkAgent::initialize_network_module(false, config_version);
4023 __retry:
4024 if (!load_agent_dll) {
4025 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": on_init_network, load dll ok";
4026
4027 std::string loaded_version = Slic3r::NetworkAgent::get_version();
4028 if (app_config && !loaded_version.empty() && loaded_version != "00.00.00.00") {
4029 // Self-heal only when a genuinely different series loaded than configured (e.g. the
4030 // configured build was unavailable and a fallback loaded). Within a series the
4031 // loaded build (02.08.01.53) differs from the series config (02.08.01) by design, so
4032 // compare series, not the raw string, and store the managed series form - a custom
4033 // config (02.08.01_custom) keeps its own name.
4034 std::string config_version = app_config->get_network_plugin_version();
4035 std::string loaded_series = network_plugin_series(loaded_version);
4036 if (network_plugin_series(config_version) != loaded_series) {
4037 std::string synced = is_series_managed_version(loaded_version) ? loaded_series : loaded_version;
4038 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": syncing config version from " << config_version
4039 << " to loaded " << loaded_version << " (stored as " << synced << ")";
4040 app_config->set_network_plugin_version(synced);
4041 app_config->save();
4042 }
4043 }
4044
4046 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": on_init_network, compatibility version";
4048 if (!bambu_source) {
4049 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": can not get bambu source module!";
4051 if (should_load_networking_plugin) {
4053 }
4054 }
4055 } else {
4056 if (try_backup) {
4058 BOOST_LOG_TRIVIAL(info) << "on_init_network, version mismatch, unload_network_module, result = " << result;
4059 load_agent_dll = Slic3r::NetworkAgent::initialize_network_module(true, config_version);
4060 try_backup = false;
4061 goto __retry;
4062 }
4063 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": on_init_network, version dismatch, need upload network module";
4064 if (should_load_networking_plugin) {
4066 }
4067 }
4068 } else {
4069 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": on_init_network, load dll failed";
4070 // A failed install can leave the config naming a build that never made it to disk;
4071 // fall back to the installed latest instead of dropping the user into the re-download
4072 // flow. Only when the configured library is genuinely absent, though - a pinned series
4073 // that is on disk but failed to load once must keep its pin, not be rewritten for good.
4074 std::string latest = get_latest_network_version();
4075 if (config_version != latest && !BBLNetworkPlugin::versioned_library_exists(config_version)
4077 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": falling back to installed " << latest;
4078 config_version = latest;
4079 app_config->set_network_plugin_version(latest);
4080 app_config->save();
4081 load_agent_dll = Slic3r::NetworkAgent::initialize_network_module(false, config_version);
4082 goto __retry;
4083 }
4084 if (should_load_networking_plugin) {
4085 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": on_init_network, need upload network module";
4087 }
4088 }
4089 }
4090 }
4091
4092 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", create network agent...");
4093 //std::string data_dir = wxStandardPaths::Get().GetUserDataDir().ToUTF8().data();
4094 std::string data_directory = data_dir();
4095
4096 // Register all printer agents before creating the network agent
4098
4099 // m_agent = new Slic3r::NetworkAgent(data_directory);
4100 std::unique_ptr<Slic3r::NetworkAgent> agent_ptr = Slic3r::create_agent_from_config(data_directory, app_config);
4101 // A direct restart_networking() replaces m_agent without deleting it, so a health check in flight
4102 // on the old agent would still report into the GUI.
4104 m_agent = agent_ptr.release();
4105
4106 if (!m_device_manager)
4107 m_device_manager = new Slic3r::DeviceManager(m_agent);
4108 else
4109 m_device_manager->set_agent(m_agent);
4110
4111 if (!m_user_manager)
4112 m_user_manager = new Slic3r::UserManager(m_agent);
4113 else
4114 m_user_manager->set_agent(m_agent);
4115
4116 // A hot reload deletes the agent the task manager was built with. It lives until restart, so repoint it
4117 // even if multi-device has since been turned off.
4118 if (m_task_manager)
4119 m_task_manager->set_agent(m_agent);
4120
4121 if (this->is_enable_multi_machine()) {
4122 if (!m_task_manager) {
4123 m_task_manager = new Slic3r::TaskManager(m_agent);
4124 m_task_manager->start();
4125 }
4126
4127 m_device_manager->EnableMultiMachine(true);
4128 } else {
4129 m_device_manager->EnableMultiMachine(false);
4130 }
4131
4132 //BBS set config dir
4133 if (m_agent) {
4134 m_agent->set_config_dir(data_directory);
4135 }
4136 //BBS start http log
4137 if (m_agent) {
4138 m_agent->init_log();
4139 }
4140
4141 //BBS set cert dir
4142 if (m_agent)
4143 m_agent->set_cert_file(resources_dir() + "/cert", "slicer_base64.cer");
4144
4145 if (m_agent) {
4147 std::string country_code = app_config->get_country_code();
4148 m_agent->set_country_code(country_code);
4149 m_agent->start();
4150 // Orca: disable Bambu telemetry up-front (before any login) so it never starts.
4152 }
4153
4154 // When using Orca cloud alongside the BBL network plugin, the BBL DLL agent still
4155 // needs to be created and configured (config dir, certs, country, start) so that
4156 // BBLPrinterAgent can use it for LAN discovery and printer communication.
4157 if (should_load_networking_plugin && !m_networking_need_update) {
4158 auto& plugin = BBLNetworkPlugin::instance();
4159 if (plugin.is_loaded() && !plugin.has_agent()) {
4160 plugin.create_agent(data_directory);
4161 }
4162 if (plugin.has_agent()) {
4163 BBLCloudServiceAgent bbl;
4164 bbl.set_config_dir(data_directory);
4165 bbl.init_log();
4166 bbl.set_cert_file(resources_dir() + "/cert", "slicer_base64.cer");
4167 bbl.set_country_code(app_config->get_country_code());
4168 // Orca: disable Bambu telemetry before start() so the DLL never spins up tracking
4169 // workers. This covers the case where the BBL plugin is loaded for LAN discovery
4170 // but the user has not registered BBL_CLOUD_PROVIDER (so m_agent->track_enable
4171 // would not reach this DLL instance).
4172 bbl.track_enable(false);
4173 bbl.track_remove_files();
4174 bbl.start();
4175 }
4176 }
4177
4178 if (!should_load_networking_plugin) {
4180 BOOST_LOG_TRIVIAL(info) << "on_init_network, unload_network_module, result = " << result;
4181
4182 if (!m_device_manager)
4183 m_device_manager = new Slic3r::DeviceManager();
4184
4185 if (!m_user_manager)
4186 m_user_manager = new Slic3r::UserManager();
4187 }
4188
4189 // A version pinned to something other than the latest series is a deliberate choice, so it
4190 // is exempt from the upgrade prompt the same way the legacy pin already is - otherwise the
4191 // dialog reappears on every launch for as long as the pin is held.
4192 const std::string pinned_version = app_config->get_network_plugin_version();
4193 const bool pinned_to_older_series = !pinned_version.empty() &&
4195
4196 if (should_load_networking_plugin && m_networking_compatible && !pinned_to_older_series) {
4197 app_config->clear_remind_network_update_later();
4198
4200 std::string latest = get_latest_network_version();
4201
4202 bool should_prompt = !app_config->is_network_update_prompt_disabled()
4203 && !app_config->is_network_version_skipped(latest)
4204 && !app_config->should_remind_network_update_later();
4205
4206 if (should_prompt) {
4207 CallAfter([this]() {
4209 });
4210 }
4211 }
4212 }
4213
4214 return true;
4215}
static bool versioned_library_exists(const std::string &version)
Definition BBLNetworkPlugin.cpp:440
void show_network_plugin_download_dialog(bool is_update=false)
Definition GUI_App.cpp:2151
void check_track_enable()
Definition GUI_App.cpp:6156
bool has_network_update_available() const
Definition GUI_App.cpp:2140
void migrate_network_plugin_config()
Definition GUI_App.cpp:1980
bool check_networking_version()
Definition GUI_App.cpp:2230
void init_networking_callbacks()
Definition GUI_App.cpp:2284
bool m_networking_need_update
Definition GUI_App.hpp:332
static void register_all_agents()
Definition NetworkAgentFactory.cpp:183
static void * get_bambu_source_entry()
Definition NetworkAgent.cpp:81
static int initialize_network_module(bool using_backup=false, const std::string &version="")
Definition NetworkAgent.cpp:69
std::unique_ptr< NetworkAgent > create_agent_from_config(const std::string &log_dir, AppConfig *app_config)
Definition NetworkAgentFactory.cpp:208

References app_config, check_networking_version(), check_track_enable(), Slic3r::create_agent_from_config(), Slic3r::data_dir(), Slic3r::NetworkAgent::get_bambu_source_entry(), get_latest_network_version(), Slic3r::NetworkAgent::get_version(), has_network_update_available(), Slic3r::BBLCloudServiceAgent::init_log(), init_networking_callbacks(), Slic3r::NetworkAgent::initialize_network_module(), Slic3r::BBLNetworkPlugin::instance(), is_enable_multi_machine(), Slic3r::is_series_managed_version(), Slic3r::is_supported_network_version(), m_agent, m_device_manager, m_networking_compatible, m_networking_need_update, m_task_manager, m_user_manager, migrate_network_plugin_config(), Slic3r::network_plugin_series(), on_init_network(), Slic3r::NetworkAgentFactory::register_all_agents(), Slic3r::resources_dir(), Slic3r::BBLCloudServiceAgent::set_cert_file(), Slic3r::BBLCloudServiceAgent::set_config_dir(), Slic3r::BBLCloudServiceAgent::set_country_code(), show_network_plugin_download_dialog(), Slic3r::BBLCloudServiceAgent::start(), Slic3r::BBLCloudServiceAgent::track_enable(), Slic3r::BBLCloudServiceAgent::track_remove_files(), Slic3r::NetworkAgent::unload_network_module(), and Slic3r::BBLNetworkPlugin::versioned_library_exists().

Referenced by on_init_inner(), on_init_network(), and restart_networking().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_shortcuts_changed()

void Slic3r::GUI::GUI_App::on_shortcuts_changed ( )
4999{
5000 m_shortcuts->save(*app_config);
5001 app_config->save();
5002 if (mainframe == nullptr)
5003 return;
5004 mainframe->update_shortcut_labels();
5005 if (Plater* plater = this->plater(); plater != nullptr) {
5006 if (GLCanvas3D* canvas = plater->get_view3D_canvas3D(); canvas != nullptr)
5007 canvas->update_shortcut_tooltips();
5008#ifdef __WXOSX__
5009 obj_list()->update_shortcut_accelerators();
5010#endif
5011 }
5012}

References app_config, m_shortcuts, mainframe, obj_list(), on_shortcuts_changed(), and plater().

Referenced by on_shortcuts_changed().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_show_check_privacy_dlg()

void Slic3r::GUI::GUI_App::on_show_check_privacy_dlg ( int online_login = 0,
const std::string & provider = ORCA_CLOUD_PROVIDER )
6834{
6835 auto evt = new wxCommandEvent(EVT_CHECK_PRIVACY_SHOW);
6836 evt->SetInt(online_login);
6837 evt->SetString(wxString::FromUTF8(provider));
6838 wxQueueEvent(this, evt);
6839}

References on_show_check_privacy_dlg().

Referenced by on_check_privacy_update(), and on_show_check_privacy_dlg().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_start_subscribe_again()

void Slic3r::GUI::GUI_App::on_start_subscribe_again ( std::string dev_id)
2858{
2859 auto start_subscribe_timer = new wxTimer(this, wxID_ANY);
2860 Bind(wxEVT_TIMER, [start_subscribe_timer, dev_id](auto& e) {
2861 start_subscribe_timer->Stop();
2862 Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
2863 if (!dev) return;
2864 MachineObject* obj = dev->get_selected_machine();
2865 if (!obj) return;
2866
2867 if ( (dev_id == obj->get_dev_id()) && obj->is_connecting() && obj->subscribe_counter > 0) {
2868 obj->subscribe_counter--;
2869 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": dev_id=" << obj->get_dev_id();
2870 }
2871 });
2872 start_subscribe_timer->Start(5000, wxTIMER_ONE_SHOT);
2873}
MachineObject * get_selected_machine()
Definition DevManager.cpp:747

References Slic3r::MachineObject::get_dev_id(), Slic3r::DeviceManager::get_selected_machine(), Slic3r::MachineObject::is_connecting(), on_start_subscribe_again(), and Slic3r::MachineObject::subscribe_counter.

Referenced by on_start_subscribe_again().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_stealth_mode_enter()

void Slic3r::GUI::GUI_App::on_stealth_mode_enter ( )
8315{
8317 BOOST_LOG_TRIVIAL(info) << "logout: on_stealth_mode_enter";
8318 // Stealth mode forces a desktop logout, but the user did not choose "Sign out": guide §8 ties
8319 // ?signout=1 to the explicit desktop sign-out only. Leave the cloud webview's own session
8320 // alone, so it is re-checked (and re-seeded with the right account) on the next open.
8321 request_user_logout(ORCA_CLOUD_PROVIDER, /*user_initiated=*/false);
8322 request_user_logout(BBL_CLOUD_PROVIDER, /*user_initiated=*/false);
8323 if (WebViewPanel* home = WebViewPanel::if_built()) {
8324 home->SendCloudProvidersInfo();
8325 }
8326}

References Slic3r::BBL_CLOUD_PROVIDER(), Slic3r::GUI::LazyInstance< WebViewPanel >::if_built(), on_stealth_mode_enter(), Slic3r::ORCA_CLOUD_PROVIDER(), request_user_logout(), and stop_sync_user_preset().

Referenced by on_stealth_mode_enter().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_update_machine_list()

void Slic3r::GUI::GUI_App::on_update_machine_list ( wxCommandEvent & evt)
5994{
5995 /* DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
5996 if (dev) {
5997 dev->add_user_subscribe();
5998 }*/
5999}

References on_update_machine_list().

Referenced by on_init_inner(), and on_update_machine_list().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_user_login()

void Slic3r::GUI::GUI_App::on_user_login ( wxCommandEvent & evt)
6166{
6167 if (!m_agent) { return; }
6168 int online_login = evt.GetInt();
6169 std::string provider = evt.GetString().ToStdString();
6170 if (provider.empty()) provider = ORCA_CLOUD_PROVIDER;
6171
6172 // check privacy before handle
6173 check_privacy_version(online_login, provider);
6175}
void check_privacy_version(int online_login=0, const std::string &provider=ORCA_CLOUD_PROVIDER)
Definition GUI_App.cpp:6871

References check_privacy_version(), check_track_enable(), m_agent, on_user_login(), and Slic3r::ORCA_CLOUD_PROVIDER().

Referenced by on_init_inner(), and on_user_login().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_user_login_handle()

void Slic3r::GUI::GUI_App::on_user_login_handle ( wxCommandEvent & evt)
6089{
6090 if (!m_agent) { return; }
6091 if (app_config->get_stealth_mode()) {
6092 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": stealth mode enabled, skipping cloud connection";
6093 return;
6094 }
6095
6096 int online_login = evt.GetInt();
6097 std::string provider = evt.GetString().ToStdString();
6098 if (provider.empty()) provider = ORCA_CLOUD_PROVIDER;
6099
6100 // Reset 401 grace period so transient token-propagation 401s
6101 // during login warmup don't trigger immediate logout.
6102 m_last_401_error_time = std::chrono::steady_clock::now();
6103
6104 m_agent->connect_server();
6105 // get machine list
6106 DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
6107 if (!dev) return;
6108
6109 boost::thread update_thread = boost::thread([dev, provider] {
6110 dev->update_user_machine_list_info(provider);
6111 });
6112
6113 if (online_login && provider == ORCA_CLOUD_PROVIDER) {
6114 // The steps below run synchronously on the UI thread (cloud plugin fetch and
6115 // user-preset load both block on network/disk). Show an indeterminate progress
6116 // dialog so the window isn't frozen without feedback. Percentages are cosmetic
6117 // milestones, not measured progress.
6118 ProgressDialog dlg(_L("Loading"), _L("Syncing your account…"), 100, mainframe, wxPD_AUTO_HIDE | wxPD_APP_MODAL);
6119
6120 dlg.Update(10, _L("Migrating presets…"));
6124
6125 dlg.Update(40, _L("Fetching plugins…"));
6127 if (m_plugins_dlg)
6128 m_plugins_dlg->update_plugin_dialog_ui();
6129
6130 dlg.Update(70, _L("Loading user presets…"));
6131 preset_bundle->load_user_presets(m_agent->get_user_id(provider), ForwardCompatibilitySubstitutionRule::Enable);
6132 mainframe->update_side_preset_ui();
6133
6134 dlg.Update(100);
6135 GUI::wxGetApp().mainframe->show_sync_dialog();
6136 }
6137
6138 // Ensure sync thread starts after login completes (regardless of login type).
6139 // Safe: start_sync_user_preset() has a dedup guard (m_user_sync_token) to prevent duplicate threads.
6140 if (app_config->get("sync_user_preset") == "true") {
6142 }
6143
6144 // Re-seed the embedded OrcaCloud pane if it is already open, so it picks up the new session
6145 // without waiting for the next open. On a fresh login or account switch this invalidates any
6146 // in-flight handoff for the previous account and loads the Start URL with the new user_id, so
6147 // the page drops the old account and re-requests (guide §8).
6149 m_cloud_handoff_state.clear();
6150 if (WebViewPanel* home = WebViewPanel::if_built())
6151 if (home->cloud_mode_active())
6152 home->set_cloud_mode(true, cloud_webview_handoff(m_cloud_open_path));
6153}
wxString cloud_webview_handoff(const std::string &next=std::string())
Definition GUI_App.cpp:6001
PluginsDialog * m_plugins_dlg
Definition GUI_App.hpp:645
std::string m_cloud_open_path
Definition GUI_App.hpp:372
void start_sync_user_preset(bool with_progress_dlg=false)
Definition GUI_App.cpp:7899
void remove_user_presets()
Definition GUI_App.cpp:7171
void fetch_plugins_from_cloud(std::vector< std::string > *out_not_found=nullptr, std::vector< std::string > *out_unauthorized=nullptr)
Definition PluginManager.cpp:1608

References _L, app_config, cloud_webview_handoff(), Slic3r::Enable, enable_user_preset_folder(), Slic3r::GUI::LazyInstance< WebViewPanel >::if_built(), Slic3r::PluginManager::instance(), m_agent, m_cloud_handoff_gen, m_cloud_handoff_state, m_cloud_open_path, m_last_401_error_time, m_plugins_dlg, mainframe, maybe_migrate_user_presets_on_login(), on_user_login_handle(), Slic3r::ORCA_CLOUD_PROVIDER(), preset_bundle, remove_user_presets(), start_sync_user_preset(), Slic3r::GUI::ProgressDialog::Update(), and Slic3r::DeviceManager::update_user_machine_list_info().

Referenced by on_init_inner(), and on_user_login_handle().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnExceptionInMainLoop()

bool Slic3r::GUI::GUI_App::OnExceptionInMainLoop ( )
overridevirtual
9581{
9583 return false;
9584}
static void generic_exception_handle()
Definition GUI_App.cpp:852

References Slic3r::GUI::generic_exception_handle(), and OnExceptionInMainLoop().

Referenced by OnExceptionInMainLoop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnExit()

int Slic3r::GUI::GUI_App::OnExit ( )
override
2912{
2915
2916 if (m_device_manager) {
2917 delete m_device_manager;
2918 m_device_manager = nullptr;
2919 }
2920
2921 if (m_user_manager) {
2922 delete m_user_manager;
2923 m_user_manager = nullptr;
2924 }
2925
2926 // Clear the printer agent cache before destroying the NetworkAgent.
2927 // This disconnects all cached agents and releases their shared_ptrs,
2928 // ensuring clean thread shutdown before the agent is deleted.
2930
2931 if (m_agent) {
2933 // BBS avoid a crash on mac platform
2934#ifdef __WINDOWS__
2935 m_agent->start_discovery(false, false);
2936#endif
2937 delete m_agent;
2938 m_agent = nullptr;
2939 }
2940
2941 // Orca: clean up encrypted bbl network log file if plugin is used
2942 // No point to keep them as they are encrypted and can't be used for debugging
2943 try {
2944 auto log_folder = boost::filesystem::path(data_dir()) / "log";
2945 const std::string filePattern = R"(debug_network_.*\.log\.enc)";
2946 std::regex pattern(filePattern);
2947 if (boost::filesystem::exists(log_folder)) {
2948 std::vector<boost::filesystem::path> network_logs;
2949 for (auto& it : boost::filesystem::directory_iterator(log_folder)) {
2950 auto temp_path = it.path();
2951 if (boost::filesystem::is_regular_file(temp_path) && std::regex_match(temp_path.filename().string(), pattern)) {
2952 network_logs.push_back(temp_path.filename());
2953 }
2954 }
2955 for (auto f : network_logs) {
2956 boost::filesystem::remove(f);
2957 }
2958 }
2959 } catch (...) {
2960 BOOST_LOG_TRIVIAL(error) << "Failed to clean up encrypt bbl network log file";
2961 }
2962
2963 return wxApp::OnExit();
2964}
void stop_http_server()
Definition GUI_App.cpp:8360
static double f(double x, double z_sin, double z_cos, bool vertical, bool flip)
Definition FillGyroid.cpp:124

References Slic3r::NetworkAgentFactory::clear_printer_agent_cache(), Slic3r::data_dir(), Slic3r::f(), m_agent, m_device_manager, m_user_manager, OnExit(), stop_http_server(), and stop_sync_user_preset().

Referenced by OnExit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnInit()

bool Slic3r::GUI::GUI_App::OnInit ( )
override
2901{
2902 try {
2903 return on_init_inner();
2904 } catch (const std::exception& e) {
2905 BOOST_LOG_TRIVIAL(fatal) << "OnInit Got Fatal error: " << e.what();
2907 return false;
2908 }
2909}
bool on_init_inner()
Definition GUI_App.cpp:3160

References Slic3r::GUI::generic_exception_handle(), on_init_inner(), and OnInit().

Referenced by OnInit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ open_browser_with_warning_dialog()

bool Slic3r::GUI::GUI_App::open_browser_with_warning_dialog ( const wxString & url,
int flags = 0 )
10217{
10218 return wxLaunchDefaultBrowser(url, flags);
10219}

References open_browser_with_warning_dialog().

Referenced by open_browser_with_warning_dialog(), and open_web_page_localized().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ open_exportpresetbundledialog()

void Slic3r::GUI::GUI_App::open_exportpresetbundledialog ( size_t open_on_tab = 0,
const std::string & highlight_option = std::string() )
9051{
9052 bool app_layout_changed = false;
9053 {
9054 ExportPresetBundleDialog dlg(mainframe, open_on_tab, highlight_option);
9055 dlg.ShowModal();
9056 this->plater_->get_current_canvas3D()->force_set_focus();
9057 #if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
9058 if (dlg.seq_top_layer_only_changed() || dlg.seq_seq_top_gcode_indices_changed())
9059 #else
9060 if (dlg.seq_top_layer_only_changed())
9061 #endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
9062 this->plater_->reload_print();
9063 }
9064}

References mainframe, open_exportpresetbundledialog(), plater_, Slic3r::GUI::ExportPresetBundleDialog::seq_top_layer_only_changed(), and Slic3r::GUI::DPIAware< P >::ShowModal().

Referenced by open_exportpresetbundledialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ open_mall_page_dialog()

void Slic3r::GUI::GUI_App::open_mall_page_dialog ( )
9750{
9751 std::string host_url;
9752 std::string model_url;
9753 std::string link_url;
9754
9755 int result = -1;
9756
9757 //model api url
9758 host_url = get_model_http_url(app_config->get_country_code());
9759
9760 //model url
9761
9762 wxString language_code = this->current_language_code().BeforeFirst('_');
9763 model_url = language_code.ToStdString();
9764
9765 if (getAgent() && mainframe) {
9766
9767 //login already
9768 if (getAgent()->is_user_login()) {
9769 std::string ticket;
9770 result = getAgent()->request_bind_ticket(&ticket);
9771
9772 if(result == 0){
9773 link_url = host_url + "api/sign-in/ticket?to=" + host_url + url_encode(model_url) + "&ticket=" + ticket;
9774 }
9775 }
9776 }
9777
9778 if (result < 0) {
9779 link_url = host_url + model_url;
9780 }
9781
9782 if (link_url.find("?") != std::string::npos) {
9783 link_url += "&from=orcaslicer";
9784 } else {
9785 link_url += "?from=orcaslicer";
9786 }
9787
9788 wxLaunchDefaultBrowser(link_url);
9789}
bool is_user_login(const std::string &provider=ORCA_CLOUD_PROVIDER)
Definition GUI_App.cpp:5317
std::string url_encode(std::string value)
Definition GUI_App.cpp:9834
std::string get_model_http_url(std::string country_code)
Definition GUI_App.cpp:1355
NetworkAgent * getAgent()
Definition GUI_App.hpp:409
int request_bind_ticket(std::string *ticket)
Definition NetworkAgent.cpp:1118

References app_config, current_language_code(), get_model_http_url(), getAgent(), is_user_login(), mainframe, open_mall_page_dialog(), and url_encode().

Referenced by handle_web_request(), and open_mall_page_dialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ open_orca_cloud()

void Slic3r::GUI::GUI_App::open_orca_cloud ( const std::string & next = std::string())
5709{
5710 // Remembered so a login while the pane is open re-seeds the same page rather than the default.
5711 m_cloud_open_path = next;
5712 // Deferred: set_cloud_mode() may create the second native webview, so this must not run inside
5713 // the caller's frame (a webview script-message callback or an ImGui frame).
5714 CallAfter([this]() {
5715 if (mainframe != nullptr)
5716 mainframe->select_tab(TAB_ID_HOME);
5717 // The Home page is built lazily, so the tab switch may not have created it yet: ensure() builds
5718 // it if needed, matching what showing the tab does, rather than dropping the open request.
5719 if (WebViewPanel* home = WebViewPanel::ensure())
5721 });
5722}
static WebViewPanel * ensure()
Definition Lazy.hpp:186
static wxString cloud_page_url(NetworkAgent *agent, const std::string &path)
Definition GUI_App.cpp:345

References Slic3r::GUI::cloud_page_url(), cloud_webview_handoff(), Slic3r::GUI::LazyInstance< WebViewPanel >::ensure(), m_agent, m_cloud_open_path, mainframe, open_orca_cloud(), and TAB_ID_HOME.

Referenced by handle_web_request(), and open_orca_cloud().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ open_plugins_dialog()

void Slic3r::GUI::GUI_App::open_plugins_dialog ( size_t open_on_tab = 0,
const std::string & highlight_option = std::string() )
8909{
8910 if (m_plugins_dlg) {
8911 m_plugins_dlg->Show();
8912 m_plugins_dlg->Raise();
8913 return;
8914 }
8915
8916 try {
8917 m_plugins_dlg = new PluginsDialog(mainframe, wxID_ANY, _L("Plugins"));
8918 m_plugins_dlg->set_open_terminal_dlg_fn();
8919 m_plugins_dlg->Bind(wxEVT_DESTROY, [this](wxWindowDestroyEvent& event) {
8920 if (event.GetEventObject() == m_plugins_dlg)
8921 m_plugins_dlg = nullptr;
8922 event.Skip();
8923 });
8924
8925 m_plugins_dlg->Show();
8926 m_plugins_dlg->Raise();
8927 } catch (const std::exception& e) {
8928 BOOST_LOG_TRIVIAL(error) << "open_plugins_dialog failed: " << e.what();
8929 if (m_plugins_dlg) {
8930 m_plugins_dlg->Destroy();
8931 m_plugins_dlg = nullptr;
8932 }
8933 wxMessageBox(wxString::Format(_L("Failed to open the Plugins dialog:\n%s"), from_u8(e.what())), _L("Plugins"),
8934 wxOK | wxICON_ERROR, mainframe);
8935 } catch (...) {
8936 BOOST_LOG_TRIVIAL(error) << "open_plugins_dialog failed with a non-standard exception";
8937 if (m_plugins_dlg) {
8938 m_plugins_dlg->Destroy();
8939 m_plugins_dlg = nullptr;
8940 }
8941 wxMessageBox(_L("Failed to open the Plugins dialog (unknown error)."), _L("Plugins"), wxOK | wxICON_ERROR, mainframe);
8942 }
8943}

References _L, Slic3r::GUI::from_u8(), m_plugins_dlg, mainframe, and open_plugins_dialog().

Referenced by open_plugins_dialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ open_preferences() [1/2]

void Slic3r::GUI::GUI_App::open_preferences ( )
void open_preferences()
Definition GUI_App.cpp:9066
@ General
Definition Preferences.hpp:40

References Slic3r::GUI::General, and open_preferences().

Referenced by open_preferences(), and open_preferences().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ open_preferences() [2/2]

void Slic3r::GUI::GUI_App::open_preferences ( PreferencesTab tab,
const std::string & highlight_option = std::string() )
9069{
9070 // Render settings the canvas reads every frame; a change needs one redraw to show.
9071 static constexpr const char* opengl_render_setting_keys[] = {
9075 };
9076 std::vector<std::string> previous_opengl_render_settings;
9077 for (const char* key : opengl_render_setting_keys)
9078 previous_opengl_render_settings.emplace_back(app_config->get(key));
9079
9080 bool need_recreate_gui = false;
9081 std::string pending_language;
9082 {
9083 // the dialog needs to be destroyed before the call to recreate_GUI()
9084 // or sometimes the application crashes into wxDialogBase() destructor
9085 // so we put it into an inner scope
9086 PreferencesDialog dlg(mainframe);
9087 dlg.select_tab(tab, highlight_option);
9088 dlg.ShowModal();
9089 need_recreate_gui = dlg.recreate_GUI();
9090 pending_language = dlg.pending_language();
9091 if (!need_recreate_gui) {
9092 this->plater_->get_current_canvas3D()->force_set_focus();
9093#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
9094 if (dlg.seq_top_layer_only_changed() || dlg.seq_seq_top_gcode_indices_changed())
9095#else
9096 if (dlg.seq_top_layer_only_changed())
9097#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
9098 this->plater_->reload_print();
9099#ifdef _WIN32
9100 if (is_editor()) {
9101 if (app_config->get("associate_3mf") == "true")
9102 associate_files(L"3mf");
9103 if (app_config->get("associate_stl") == "true")
9104 associate_files(L"stl");
9105 if (app_config->get("associate_step") == "true") {
9106 associate_files(L"step");
9107 associate_files(L"stp");
9108 }
9109 associate_url(L"orcaslicer");
9110 }
9111 else {
9112 if (app_config->get("associate_gcode") == "true")
9113 associate_files(L"gcode");
9114 }
9115#endif // _WIN32
9116 }
9117 }
9118
9119 bool opengl_render_settings_changed = false;
9120 for (size_t i = 0; i < previous_opengl_render_settings.size(); ++i)
9121 opengl_render_settings_changed |= app_config->get(opengl_render_setting_keys[i]) != previous_opengl_render_settings[i];
9122 if (opengl_render_settings_changed && !need_recreate_gui && this->plater_ != nullptr) {
9123 this->plater_->set_current_canvas_as_dirty();
9124 this->plater_->get_current_canvas3D()->force_set_focus();
9125 }
9126
9127 if (!pending_language.empty()) {
9128 const std::string previous_language = app_config->get("language");
9129 app_config->set("language", pending_language);
9130 if (!load_language(wxString::FromUTF8(pending_language), false)) {
9131 app_config->set("language", previous_language);
9132 if (this->plater_)
9133 this->plater_->get_current_canvas3D()->force_set_focus();
9134 return;
9135 }
9136 // Built-in Speed Dial command titles are copied from the catalog at init and don't follow a
9137 // live locale switch; rebuild them in the new language before the GUI (and palette) rebuilds.
9138 m_action_registry.relocalize_builtins();
9139 }
9140
9141 if (need_recreate_gui)
9142 recreate_GUI(_L("Changing application language"));
9143}
#define SETTING_OPENGL_FXAA_ENABLED
Definition AppConfig.hpp:35
#define SETTING_OPENGL_SHOW_RENDER_TIMINGS
Definition AppConfig.hpp:40
#define SETTING_OPENGL_SCENE_CACHE
Definition AppConfig.hpp:37
#define SETTING_OPENGL_REALISTIC_SHADOWS
Definition AppConfig.hpp:46
#define SETTING_OPENGL_FPS_CAP
Definition AppConfig.hpp:36
#define SETTING_OPENGL_SHOW_FPS_OVERLAY
Definition AppConfig.hpp:39
#define SETTING_OPENGL_REALISTIC_GLOSS
Definition AppConfig.hpp:50
#define SETTING_OPENGL_SKIP_IDENTICAL_FRAMES
Definition AppConfig.hpp:38
void recreate_GUI(const wxString &message)
Definition GUI_App.cpp:4922

References _L, app_config, associate_files(), associate_url(), is_editor(), L, load_language(), m_action_registry, mainframe, open_preferences(), Slic3r::GUI::PreferencesDialog::pending_language(), plater_, recreate_GUI(), Slic3r::GUI::PreferencesDialog::recreate_GUI(), Slic3r::GUI::PreferencesDialog::select_tab(), Slic3r::GUI::PreferencesDialog::seq_top_layer_only_changed(), SETTING_OPENGL_FPS_CAP, SETTING_OPENGL_FXAA_ENABLED, SETTING_OPENGL_REALISTIC_GLOSS, SETTING_OPENGL_REALISTIC_SHADOWS, SETTING_OPENGL_SCENE_CACHE, SETTING_OPENGL_SHOW_FPS_OVERLAY, SETTING_OPENGL_SHOW_RENDER_TIMINGS, SETTING_OPENGL_SKIP_IDENTICAL_FRAMES, and Slic3r::GUI::DPIAware< P >::ShowModal().

Here is the call graph for this function:

◆ open_presetbundledialog()

void Slic3r::GUI::GUI_App::open_presetbundledialog ( size_t open_on_tab = 0,
const std::string & highlight_option = std::string() )
8884{
8885 bool app_layout_changed = false;
8886 {
8887
8889 {
8890 return;
8891 }
8892 m_preset_bundle_dlg = new PresetBundleDialog(mainframe, open_on_tab, highlight_option);
8893 m_preset_bundle_dlg->Bind(wxEVT_DESTROY, [this](wxWindowDestroyEvent&) {
8895 m_preset_bundle_dlg = nullptr;
8896 });
8897 // PresetBundleDialog dlg(mainframe, open_on_tab, highlight_option);
8898 m_preset_bundle_dlg->ShowModal();
8899 if (m_preset_bundle_dlg) {
8900 m_preset_bundle_dlg->Destroy();
8901 m_preset_bundle_dlg = nullptr;
8902 }
8903 this->plater_->get_current_canvas3D()->force_set_focus();
8904
8905 }
8906}
PresetBundleDialog * m_preset_bundle_dlg
Definition GUI_App.hpp:644

References m_preset_bundle_dlg, mainframe, open_presetbundledialog(), and plater_.

Referenced by open_presetbundledialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ open_publish_page_dialog()

void Slic3r::GUI::GUI_App::open_publish_page_dialog ( )
9792{
9793 std::string host_url;
9794 std::string model_url;
9795 std::string link_url;
9796
9797 int result = -1;
9798
9799 //model api url
9800 host_url = get_model_http_url(app_config->get_country_code());
9801
9802 //publish url
9803 wxString language_code = this->current_language_code().BeforeFirst('_');
9804 model_url += (language_code.ToStdString() + "/my/models/publish");
9805
9806 if (getAgent() && mainframe) {
9807
9808 //login already
9809 if (getAgent()->is_user_login()) {
9810 std::string ticket;
9811 result = getAgent()->request_bind_ticket(&ticket);
9812
9813 if (result == 0) {
9814 link_url = host_url + "api/sign-in/ticket?to=" + host_url + url_encode(model_url) + "&ticket=" + ticket;
9815 }
9816 }
9817 }
9818
9819 if (result < 0) {
9820 link_url = host_url + model_url;
9821 }
9822
9823 wxLaunchDefaultBrowser(link_url);
9824}

References app_config, current_language_code(), get_model_http_url(), getAgent(), is_user_login(), mainframe, open_publish_page_dialog(), and url_encode().

Referenced by open_publish_page_dialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ open_speed_dial()

void Slic3r::GUI::GUI_App::open_speed_dial ( )
9036{
9037 if (!mainframe)
9038 return;
9039 if (!m_speed_dial_dialog) {
9040 m_speed_dial_dialog = new SpeedDialWebDialog(mainframe);
9041 m_speed_dial_dialog->Bind(wxEVT_DESTROY, [this](wxWindowDestroyEvent& event) {
9042 if (event.GetEventObject() == m_speed_dial_dialog)
9043 m_speed_dial_dialog = nullptr;
9044 event.Skip();
9045 });
9046 }
9047 m_speed_dial_dialog->request_show();
9048}
SpeedDialWebDialog * m_speed_dial_dialog
Definition GUI_App.hpp:646

References m_speed_dial_dialog, mainframe, and open_speed_dial().

Referenced by open_speed_dial().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ open_terminal_dialog()

void Slic3r::GUI::GUI_App::open_terminal_dialog ( )
9006{
9007 // Reached from the plugins dialog's webview ("open_terminal" command), i.e. from
9008 // inside the webview script-message callback, which GTK/macOS deliver synchronously
9009 // (see ui_create_window in PluginHostUi.cpp). TerminalDialog hosts a webview of its
9010 // own, so creating or presenting it on that stack is the same class as the Linux
9011 // gtk_window_present crash — defer all window work to a clean main-loop iteration.
9012 CallAfter([this]() {
9013 if (m_terminal_dlg) {
9014 // Re-front the existing window; guard Show() per #13657 (GTK re-enters
9015 // layout when showing an already-visible window).
9016 if (!m_terminal_dlg->IsShown())
9017 m_terminal_dlg->Show();
9018 m_terminal_dlg->Raise();
9019 return;
9020 }
9021
9022 m_terminal_dlg = new TerminalDialog(mainframe, wxID_ANY, _L("Plugin Terminal"),
9023 wxDefaultPosition, wxSize(820, 600));
9024 m_terminal_dlg->Bind(wxEVT_DESTROY, [this](wxWindowDestroyEvent& event) {
9025 if (event.GetEventObject() == m_terminal_dlg)
9026 m_terminal_dlg = nullptr;
9027 event.Skip();
9028 });
9029
9030 // Show() alone activates and fronts a freshly created window on every platform.
9031 m_terminal_dlg->Show();
9032 });
9033}
TerminalDialog * m_terminal_dlg
Definition GUI_App.hpp:647

References _L, m_terminal_dlg, mainframe, and open_terminal_dialog().

Referenced by open_terminal_dialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ open_web_page_localized()

void Slic3r::GUI::GUI_App::open_web_page_localized ( const std::string & http_address)
9950{
9951 open_browser_with_warning_dialog(http_address + "&lng=" + this->current_language_code_safe());
9952}
wxString current_language_code_safe() const
Definition GUI_App.cpp:9916
bool open_browser_with_warning_dialog(const wxString &url, int flags=0)
Definition GUI_App.cpp:10216

References current_language_code_safe(), open_browser_with_warning_dialog(), and open_web_page_localized().

Referenced by open_web_page_localized().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ other_instance_message_handler()

OtherInstanceMessageHandler * Slic3r::GUI::GUI_App::other_instance_message_handler ( )
inline
808{ return m_other_instance_message_handler.get(); }

References m_other_instance_message_handler.

Referenced by on_init_inner().

Here is the caller graph for this function:

◆ params_dialog()

ParamsDialog * Slic3r::GUI::GUI_App::params_dialog ( )
9727{
9728 if (mainframe)
9729 return mainframe->m_param_dialog;
9730 return nullptr;
9731}

References mainframe, and params_dialog().

Referenced by params_dialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ params_panel()

ParamsPanel * Slic3r::GUI::GUI_App::params_panel ( )
9720{
9721 if (mainframe)
9722 return mainframe->m_param_panel;
9723 return nullptr;
9724}

References mainframe, and params_panel().

Referenced by params_panel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ persist_window_geometry()

void Slic3r::GUI::GUI_App::persist_window_geometry ( wxTopLevelWindow * window,
bool default_maximized = false )
5188{
5189 const std::string name = into_u8(window->GetName());
5190
5191 window->Bind(wxEVT_CLOSE_WINDOW, [=](wxCloseEvent &event) {
5192 BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< ": received wxEVT_CLOSE_WINDOW, trigger save for window_mainframe";
5193 window_pos_save(window, "mainframe");
5194 event.Skip();
5195 });
5196
5197 if (window_pos_restore(window, "mainframe", default_maximized)) {
5198 on_window_geometry(window, [=]() {
5199 window_pos_sanitize(window);
5200 });
5201 } else {
5202 on_window_geometry(window, [=]() {
5203 window_pos_center(window);
5204 });
5205 }
5206}
void window_pos_save(wxTopLevelWindow *window, const std::string &name)
Definition GUI_App.cpp:10090
void window_pos_center(wxTopLevelWindow *window)
Definition GUI_App.cpp:10146
void window_pos_sanitize(wxTopLevelWindow *window)
Definition GUI_App.cpp:10128
bool window_pos_restore(wxTopLevelWindow *window, const std::string &name, bool default_maximized=false)
Definition GUI_App.cpp:10100
void on_window_geometry(wxTopLevelWindow *tlw, std::function< void()> callback)
Definition GUI_Utils.cpp:166

References Slic3r::GUI::into_u8(), Slic3r::GUI::on_window_geometry(), persist_window_geometry(), window_pos_center(), window_pos_restore(), window_pos_sanitize(), and window_pos_save().

Referenced by persist_window_geometry().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ plater() [1/2]

◆ plater() [2/2]

const Plater * Slic3r::GUI::GUI_App::plater ( ) const
9715{
9716 return plater_;
9717}

References plater(), and plater_.

Here is the call graph for this function:

◆ popup_ping_bind_dialog()

void Slic3r::GUI::GUI_App::popup_ping_bind_dialog ( )
9839{
9840 if (m_ping_code_binding_dialog == nullptr) {
9841 m_ping_code_binding_dialog = new PingCodeBindDialog();
9842 m_ping_code_binding_dialog->ShowModal();
9844 }
9845}
void remove_ping_bind_dialog()
Definition GUI_App.cpp:9847
PingCodeBindDialog * m_ping_code_binding_dialog
Definition GUI_App.hpp:756

References m_ping_code_binding_dialog, popup_ping_bind_dialog(), and remove_ping_bind_dialog().

Referenced by popup_ping_bind_dialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ post_init()

void Slic3r::GUI::GUI_App::post_init ( )
937{
938 assert(initialized());
939 if (! this->initialized())
940 throw Slic3r::RuntimeError("Calling post_init() while not yet initialized");
941
942#if wxUSE_WEBVIEW_EDGE
943 // Ensure the Microsoft WebView2 runtime is installed before any WebView is
944 // created. The setup wizard and several dialogs render entirely through
945 // WebView2; without the runtime they come up blank. This runs here (not in the
946 // constructor) so that wxWidgets is fully initialized and the event loop is
947 // running, and so it precedes the first WebView creation (the setup wizard).
948 init_webview_runtime();
949#endif
950
951 m_open_method = "double_click";
952 bool switch_to_3d = false;
953
954 if (!this->init_params->input_files.empty()) {
955
956 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", init with input files, size %1%, input_gcode %2%")
957 %this->init_params->input_files.size() %this->init_params->input_gcode;
958
959 switch_to_3d = true;
960
961 const auto first_url = this->init_params->input_files.front();
962 if (this->init_params->input_files.size() == 1 && is_supported_open_protocol(first_url)) {
963 start_download(first_url);
964 m_open_method = "url";
965 } else {
966 if (this->init_params->input_gcode) {
967 mainframe->select_tab(TAB_ID_PREPARE);
968 plater_->select_view_3D("3D");
969 this->plater()->load_gcode(from_u8(this->init_params->input_files.front()));
970 m_open_method = "gcode";
971 } else {
972 mainframe->select_tab(TAB_ID_PREPARE);
973 plater_->select_view_3D("3D");
974 wxArrayString input_files;
975 for (auto& file : this->init_params->input_files) {
976 input_files.push_back(wxString::FromUTF8(file));
977 }
978 this->plater()->set_project_filename(_L("Untitled"));
979 this->plater()->load_files(input_files);
980 try {
981 if (!input_files.empty()) {
982 std::string file_path = input_files.front().ToStdString();
983 std::filesystem::path path(file_path);
984 m_open_method = "file_" + path.extension().string();
985 }
986 } catch (...) {
987 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ", file path exception!";
988 m_open_method = "file";
989 }
990 }
991 }
992 }
993
994//#if BBL_HAS_FIRST_PAGE
995 bool slow_bootup = false;
996 if (app_config->get("slow_bootup") == "true") {
997 slow_bootup = true;
998 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", slow bootup, won't render gl here.";
999 }
1000 // Starting on Home, the GL resources load at idle so Home paints first and Prepare is never
1001 // shown.
1002 const bool gl_at_idle = !starts_on_prepare() && is_editor();
1003 if (!switch_to_3d && gl_at_idle) {
1004 plater_->select_view_3D("3D");
1005 } else if (!switch_to_3d) {
1006 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", begin load_gl_resources";
1007#ifndef __linux__
1008 mainframe->Freeze();
1009#endif
1010 plater_->canvas3D()->enable_render(false);
1011 mainframe->select_prepare_for_gl_init();
1012 plater_->select_view_3D("3D");
1013 //BBS init the opengl resource here
1014 if (!plater_->canvas3D()->get_wxglcanvas()->IsShownOnScreen() ||
1015 !plater_->canvas3D()->make_current_for_postinit()) {
1016 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": glcontext not ready, postpone init";
1017 plater_->canvas3D()->enable_render(true);
1018 plater_->canvas3D()->set_as_dirty();
1019#ifdef __linux__
1020 // Wayland/EGL may not have committed the GL surface yet; ask the
1021 // idle loop to retry post_init when the canvas is actually mapped.
1022 // Without this, GL function pointers stay null and the first
1023 // Preview focus crashes in Camera::apply_viewport.
1024 m_post_initialized = false;
1025 return;
1026#endif
1027 } else {
1028 Size canvas_size = plater_->canvas3D()->get_canvas_size();
1029 wxGetApp().imgui()->set_display_size(static_cast<float>(canvas_size.get_width()), static_cast<float>(canvas_size.get_height()));
1030 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", start to init opengl";
1031 wxGetApp().init_opengl();
1032
1033 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished init opengl";
1034 plater_->canvas3D()->init();
1035
1036 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished init canvas3D";
1037 wxGetApp().imgui()->new_frame();
1038
1039 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished init imgui frame";
1040 plater_->canvas3D()->enable_render(true);
1041
1042 if (!slow_bootup) {
1043 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", start to render a first frame for test";
1044 plater_->canvas3D()->render(false);
1045 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished rendering a first frame for test";
1046 }
1047 }
1048 if (starts_on_prepare())
1049 mainframe->select_tab(TAB_ID_PREPARE);
1050#ifndef __linux__
1051 mainframe->Thaw();
1052#endif
1053 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", end load_gl_resources";
1054 }
1055
1056 plater_->trigger_restore_project(1);
1057 //#endif
1058 mainframe->prebuild_pages_when_idle();
1059
1060 //BBS: remove GCodeViewer as seperate APP logic
1061 /*if (this->init_params->start_as_gcodeviewer) {
1062 if (! this->init_params->input_files.empty())
1063 this->plater()->load_gcode(wxString::FromUTF8(this->init_params->input_files[0].c_str()));
1064 }
1065 else
1066 {
1067 if (! this->init_params->preset_substitutions.empty())
1068 show_substitutions_info(this->init_params->preset_substitutions);
1069
1070#if 0
1071 // Load the cummulative config over the currently active profiles.
1072 //FIXME if multiple configs are loaded, only the last one will have an effect.
1073 // We need to decide what to do about loading of separate presets (just print preset, just filament preset etc).
1074 // As of now only the full configs are supported here.
1075 if (!m_print_config.empty())
1076 this->gui->mainframe->load_config(m_print_config);
1077#endif
1078 if (! this->init_params->load_configs.empty())
1079 // Load the last config to give it a name at the UI. The name of the preset may be later
1080 // changed by loading an AMF or 3MF.
1081 //FIXME this is not strictly correct, as one may pass a print/filament/printer profile here instead of a full config.
1082 this->mainframe->load_config_file(this->init_params->load_configs.back());
1083 // If loading a 3MF file, the config is loaded from the last one.
1084 if (!this->init_params->input_files.empty()) {
1085 const std::vector<size_t> res = this->plater()->load_files(this->init_params->input_files);
1086 if (!res.empty() && this->init_params->input_files.size() == 1) {
1087 // Update application titlebar when opening a project file
1088 const std::string& filename = this->init_params->input_files.front();
1089 //BBS: remove amf logic as project
1090 if (boost::algorithm::iends_with(filename, ".3mf"))
1091 this->plater()->set_project_filename(filename);
1092 }
1093 }
1094 if (! this->init_params->extra_config.empty())
1095 this->mainframe->load_config(this->init_params->extra_config);
1096 }*/
1097
1098 // BBS: to be checked
1099#if 1
1100 // show "Did you know" notification
1101 if (app_config->get("show_hints") == "true" && !is_gcode_viewer()) {
1102 plater_->get_notification_manager()->push_hint_notification(false);
1103 }
1104#endif
1105
1106 hms_query = new HMSQuery();
1107
1108 m_show_gcode_window = app_config->get_bool("show_gcode_window");
1111 }
1112
1113 // Start preset sync after project opened, otherwise we could have preset change during project opening which could cause crash
1114 if (app_config->get("sync_user_preset") == "true") {
1115 // BBS loading user preset
1116 // Always async, not such startup step
1117 // BOOST_LOG_TRIVIAL(info) << "Loading user presets...";
1118 // scrn->SetText(_L("Loading user presets..."));
1119 if (m_agent) {
1121 }
1122 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " sync_user_preset: true";
1123 } else {
1124 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " sync_user_preset: false";
1125 }
1126
1127 // The extra CallAfter() is needed because of Mac, where this is the only way
1128 // to popup a modal dialog on start without screwing combo boxes.
1129 // This is ugly but I honestly found no better way to do it.
1130 // Neither wxShowEvent nor wxWindowCreateEvent work reliably.
1131 if (this->preset_updater) { // G-Code Viewer does not initialize preset_updater.
1132 CallAfter([this] {
1133 bool cw_showed = this->config_wizard_startup();
1134
1135 if (!app_config->get_stealth_mode()) {
1136 std::string http_url = get_http_url(app_config->get_country_code());
1137 std::string language = GUI::into_u8(current_language_code());
1138 std::string network_ver = Slic3r::NetworkAgent::get_version();
1139 bool sys_preset = app_config->get("sync_system_preset") == "true";
1140 this->preset_updater->sync(http_url, language, network_ver, sys_preset ? preset_bundle : nullptr);
1141 }
1142
1143 this->check_new_version_sf();
1144 if (!cw_showed)
1146 const auto cloud_provider = get_printer_cloud_provider();
1147 if (is_user_login(cloud_provider) && !app_config->get_stealth_mode()) {
1148 // this->check_privacy_version(0);
1149 request_user_handle(0, cloud_provider);
1150 }
1151 });
1152 }
1153
1154 // Orca: notify users upgrading from a pre-2.4.0 version that profile syncing
1155 // moved from Bambu Cloud to Orca Cloud.
1157 && *m_last_config_version < Semver(2, 4, 0)) {
1158 CallAfter([] {
1159 const wxString wiki_url = "https://www.orcaslicer.com/wiki/user_profiles/user_profiles.html#profiles-missing-after-updating-from-bambu-cloud";
1160 MessageDialog dlg(nullptr,
1161 _L("Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud instead of Bambu Cloud.\n\n"
1162 "To migrate your existing profiles, log in to Orca Cloud and they will be transferred automatically. "
1163 "To learn more about how OrcaSlicer stores and syncs your profiles, or to migrate your presets manually, check out our wiki.\n\n"
1164 "If you did not use Bambu Cloud to sync profiles, this change does not affect you and you can safely ignore this message."),
1165 _L("Profile syncing change"),
1166 wxOK,
1167 "",
1168 _L("Learn more"),
1169 [wiki_url](const wxString &) { wxLaunchDefaultBrowser(wiki_url); });
1170 // Hack: the "Learn more" link renders the message in a wxHtmlWindow whose
1171 // height is underestimated for multi-paragraph text, leaving a scrollbar.
1172 // The html sits in a proportion-1 sizer chain, so grow the dialog (never
1173 // shrink it below its content width) to give the text enough room.
1174 const wxSize sz = dlg.GetSize();
1175 dlg.SetSize(std::max(sz.x, dlg.FromDIP(280)), std::max(sz.y, dlg.FromDIP(200)));
1176 dlg.CenterOnParent();
1177 dlg.ShowModal();
1178 });
1179 }
1180
1182 m_agent->set_on_ssdp_msg_fn(
1183 [this](std::string json_str) {
1184 if (!is_closing() && m_device_manager)
1185 m_device_manager->on_machine_alive(json_str);
1186 }
1187 );
1188 m_agent->set_on_http_error_fn([this](CloudEvent event, unsigned int status, std::string body) {
1189 this->handle_http_error(status, body, event.provider);
1190 });
1191 m_agent->start_discovery(true, false);
1192 }
1193
1194 //update the plugin tips
1195 CallAfter([this] {
1196 mainframe->refresh_plugin_tips();
1197 });
1198
1199 // remove old log files over LOG_FILES_MAX_NUM
1200 std::string log_addr = data_dir();
1201 if (!log_addr.empty()) {
1202 auto log_folder = boost::filesystem::path(log_addr) / "log";
1203 if (boost::filesystem::exists(log_folder)) {
1204 std::vector<std::pair<time_t, std::string>> files_vec;
1205 for (auto& it : boost::filesystem::directory_iterator(log_folder)) {
1206 auto temp_path = it.path();
1207 try {
1208 if (it.status().type() == boost::filesystem::regular_file) {
1209 std::time_t lw_t = boost::filesystem::last_write_time(temp_path) ;
1210 files_vec.push_back({ lw_t, temp_path.filename().string() });
1211 }
1212 } catch (const std::exception &) {
1213 }
1214 }
1215 std::sort(files_vec.begin(), files_vec.end(), [](
1216 std::pair<time_t, std::string> &a, std::pair<time_t, std::string> &b) {
1217 return a.first > b.first;
1218 });
1219
1220 while (files_vec.size() > LOG_FILES_MAX_NUM) {
1221 auto full_path = log_folder / boost::filesystem::path(files_vec[files_vec.size() - 1].second);
1222 BOOST_LOG_TRIVIAL(info) << "delete log file over " << LOG_FILES_MAX_NUM << ", filename: "<< files_vec[files_vec.size() - 1].second;
1223 try {
1224 boost::filesystem::remove(full_path);
1225 }
1226 catch (const std::exception& ex) {
1227 BOOST_LOG_TRIVIAL(error) << "failed to delete log file: "<< files_vec[files_vec.size() - 1].second << ". Error: " << ex.what();
1228 }
1229 files_vec.pop_back();
1230 }
1231 }
1232 }
1233 BOOST_LOG_TRIVIAL(info) << "finished post_init";
1234//BBS: remove the single instance currently
1235#ifdef _WIN32
1236 // Sets window property to mainframe so other instances can indentify it.
1237 OtherInstanceMessageHandler::init_windows_properties(mainframe, m_instance_hash_int);
1238#endif //WIN32
1239}
#define LOG_FILES_MAX_NUM
Definition GUI_App.hpp:51
std::string m_open_method
Definition GUI_App.hpp:914
bool config_wizard_startup()
Definition GUI_App.cpp:10164
void check_new_version_sf(bool show_tips=false, int by_user=0)
Definition GUI_App.cpp:6525
void start_download(std::string url)
Definition GUI_App.cpp:10435
bool initialized() const
Definition GUI_App.hpp:387
void check_legacy_user_filament_presets(bool by_user)
Definition GUI_App.cpp:7087
bool m_show_gcode_window
Definition GUI_App.hpp:377
std::vector< size_t > load_files(const std::vector< boost::filesystem::path > &input_files, LoadStrategy strategy=LoadStrategy::LoadModel|LoadStrategy::LoadConfig, bool ask_multi=false, bool *published_out=nullptr)
void set_project_filename(const wxString &filename)
Definition Plater.cpp:22045
void load_gcode()
Definition Plater.cpp:18139
bool is_supported_open_protocol(const std::string &url)
Definition Utils.hpp:317

References _L, app_config, check_legacy_user_filament_presets(), check_new_version_sf(), config_wizard_startup(), current_language_code(), Slic3r::data_dir(), Slic3r::GUI::from_u8(), Slic3r::GUI::Size::get_height(), get_http_url(), get_printer_cloud_provider(), Slic3r::NetworkAgent::get_version(), Slic3r::GUI::Size::get_width(), handle_http_error(), hms_query, init_params, initialized(), Slic3r::GUI::into_u8(), is_closing(), is_editor(), is_gcode_viewer(), Slic3r::is_supported_open_protocol(), is_user_login(), Slic3r::GUI::Plater::load_files(), Slic3r::GUI::Plater::load_gcode(), LOG_FILES_MAX_NUM, m_agent, m_device_manager, m_instance_hash_int, m_last_config_version, m_networking_need_update, m_open_method, m_post_initialized, m_show_gcode_window, mainframe, plater(), plater_, preset_bundle, preset_updater, Slic3r::CloudEvent::provider, request_user_handle(), Slic3r::GUI::Plater::set_project_filename(), show_network_plugin_download_dialog(), Slic3r::GUI::DPIAware< P >::ShowModal(), start_download(), start_sync_user_preset(), starts_on_prepare(), and TAB_ID_PREPARE.

Referenced by on_init_inner().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ post_logout_to_webview()

void Slic3r::GUI::GUI_App::post_logout_to_webview ( const std::string & provider)
5365{
5366 std::string logout_cmd = m_agent->build_logout_cmd(provider);
5367 if (!logout_cmd.empty()) {
5368 wxString strJS = wxString::Format("window.postMessage(%s)", logout_cmd);
5369 GUI::wxGetApp().run_script(strJS);
5370 }
5371}

References m_agent, and post_logout_to_webview().

Referenced by post_logout_to_webview(), request_user_logout(), and show_check_privacy_dlg().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ preset_deleted_from_cloud()

void Slic3r::GUI::GUI_App::preset_deleted_from_cloud ( std::string setting_id)
9469{
9470 std::scoped_lock l(mutex_delete_cache_presets);
9471
9472 // Get the preset info path BEFORE erasing from the map
9473 std::string preset_file_path = need_delete_presets[setting_id];
9474
9475 // Delete the .info file after cloud deletion is confirmed
9476 if (!preset_file_path.empty() && fs::exists(fs::path(preset_file_path))) {
9477 InstanceLock instance_lock(user_presets_lock_path());
9478 boost::nowide::remove(preset_file_path.c_str());
9479 BOOST_LOG_TRIVIAL(info) << "Deleted .info file after cloud confirmation: " << preset_file_path;
9480 }
9481
9482 // Now erase from map
9483 need_delete_presets.erase(setting_id);
9484}
std::string user_presets_lock_path(bool read_only)
Definition Preset.cpp:146

References Slic3r::GUI::mutex_delete_cache_presets, need_delete_presets, preset_deleted_from_cloud(), and Slic3r::user_presets_lock_path().

Referenced by preset_deleted_from_cloud(), and process_delete_presets().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ printhost_job_queue()

PrintHostJobQueue & Slic3r::GUI::GUI_App::printhost_job_queue ( )
inline
821{ return *m_printhost_job_queue.get(); }

References m_printhost_job_queue.

◆ process_delete_presets()

void Slic3r::GUI::GUI_App::process_delete_presets ( )
9441{
9442 std::map<std::string, std::string> delete_cache_presets = get_delete_cache_presets_lock();
9443 for (auto it = delete_cache_presets.begin(); it != delete_cache_presets.end();) {
9444 if (it->first.empty()) continue;
9445 std::string del_setting_id = it->first;
9446 int result = m_agent->delete_setting(del_setting_id);
9447 if (result == 0) {
9448 preset_deleted_from_cloud(del_setting_id);
9449 it = delete_cache_presets.erase(it);
9450 m_create_preset_blocked = { false, false, false, false, false, false };
9451 BOOST_LOG_TRIVIAL(trace) << "sync_preset: sync operation: delete success! setting id = " << del_setting_id;
9452 }
9453 else {
9454 BOOST_LOG_TRIVIAL(info) << "delete setting = " <<del_setting_id << " failed";
9455 it++;
9456 }
9457 }
9458}
std::map< std::string, std::string > get_delete_cache_presets_lock()
Definition GUI_App.cpp:9434
std::vector< bool > m_create_preset_blocked
Definition GUI_App.hpp:329
void preset_deleted_from_cloud(std::string setting_id)
Definition GUI_App.cpp:9468

References get_delete_cache_presets_lock(), m_agent, m_create_preset_blocked, preset_deleted_from_cloud(), process_delete_presets(), and Slic3r::trace().

Referenced by process_delete_presets(), and start_sync_user_preset().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_network_msg()

bool Slic3r::GUI::GUI_App::process_network_msg ( std::string dev_id,
std::string msg )
6672{
6673 if (dev_id.empty()) {
6674 if (msg == "wait_info") {
6675 BOOST_LOG_TRIVIAL(info) << "process_network_msg, wait_info";
6676 Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
6677 if (!dev)
6678 return true;
6679 MachineObject* obj = dev->get_selected_machine();
6680 if (obj && m_agent)
6681 m_agent->install_device_cert(obj->get_dev_id(), obj->is_lan_mode_printer());
6682 if (!m_show_error_msgdlg) {
6683 MessageDialog msg_dlg(nullptr, _L("Retrieving printer information, please try again later."), "", wxAPPLY | wxOK);
6684 m_show_error_msgdlg = true;
6685 msg_dlg.ShowModal();
6686 m_show_error_msgdlg = false;
6687 }
6688 return true;
6689 }
6690 else if (msg == "update_studio") {
6691 BOOST_LOG_TRIVIAL(info) << "process_network_msg, update_studio";
6692 if (!m_show_error_msgdlg) {
6693 MessageDialog msg_dlg(nullptr, _L("Please try updating OrcaSlicer and then try again."), "", wxAPPLY | wxOK);
6694 m_show_error_msgdlg = true;
6695 msg_dlg.ShowModal();
6696 m_show_error_msgdlg = false;
6697 }
6698 return true;
6699 }
6700 else if (msg == "update_fixed_studio") {
6701 BOOST_LOG_TRIVIAL(info) << "process_network_msg, update_fixed_studio";
6702 if (!m_show_error_msgdlg) {
6703 MessageDialog msg_dlg(nullptr, _L("Please try updating OrcaSlicer and then try again."), "", wxAPPLY | wxOK);
6704 m_show_error_msgdlg = true;
6705 msg_dlg.ShowModal();
6706 m_show_error_msgdlg = false;
6707 }
6708 return true;
6709 }
6710 else if (msg == "cert_expired") {
6711 BOOST_LOG_TRIVIAL(info) << "process_network_msg, cert_expired";
6712 if (!m_show_error_msgdlg) {
6713 MessageDialog msg_dlg(nullptr, _L("The certificate has expired. Please check the time settings or update OrcaSlicer and try again."), "", wxAPPLY | wxOK);
6714 m_show_error_msgdlg = true;
6715 msg_dlg.ShowModal();
6716 m_show_error_msgdlg = false;
6717 }
6718 return true;
6719 }
6720 else if (msg == "cert_revoked") {
6721 BOOST_LOG_TRIVIAL(info) << "process_network_msg, cert_revoked";
6722 if (!m_show_error_msgdlg) {
6723 MessageDialog msg_dlg(nullptr, _L("The certificate is no longer valid and the printing functions are unavailable."), "", wxAPPLY | wxOK);
6724 m_show_error_msgdlg = true;
6725 msg_dlg.ShowModal();
6726 m_show_error_msgdlg = false;
6727 }
6728 return true;
6729 }
6730 else if (msg == "update_firmware_studio") {
6731 BOOST_LOG_TRIVIAL(info) << "process_network_msg, firmware internal error";
6732 if (!m_show_error_msgdlg) {
6733 MessageDialog msg_dlg(nullptr, _L("Internal error. Please try upgrading the firmware and OrcaSlicer version. If the issue persists, contact support."), "", wxAPPLY | wxOK);
6734 m_show_error_msgdlg = true;
6735 msg_dlg.ShowModal();
6736 m_show_error_msgdlg = false;
6737 }
6738 return true;
6739 }
6740 else if (msg == "unsigned_studio") {
6741 BOOST_LOG_TRIVIAL(info) << "process_network_msg, unsigned_studio";
6742 // Plugin re-emits this on every subscribe retry; latch it so it shows
6743 // once per connection episode.
6746 MessageDialog
6747 msg_dlg(nullptr,
6748 _L("To use OrcaSlicer with Bambu Lab printers, you need to enable LAN mode and Developer mode on your printer.\n\n"
6749 "Please go to your printer's settings and:\n"
6750 "1. Turn on LAN mode\n"
6751 "2. Enable Developer mode\n\n"
6752 "Developer mode allows the printer to work exclusively through local network access, "
6753 "enabling full functionality with OrcaSlicer."),
6754 _L("Network Plug-in Restriction"), wxAPPLY | wxOK);
6755 m_show_error_msgdlg = true;
6756 msg_dlg.ShowModal();
6757 m_show_error_msgdlg = false;
6758 }
6759 return true;
6760 }
6761 }
6762 else if (msg == "device_cert_installed") {
6763 BOOST_LOG_TRIVIAL(info) << "process_network_msg, device_cert_installed";
6764 if (Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager()) {
6765 if (MachineObject* obj = dev->get_my_machine(dev_id)) {
6766 obj->update_device_cert_state(true);
6767 }
6768 }
6769 return true;
6770 }
6771 else if (msg == "device_cert_uninstalled") {
6772 BOOST_LOG_TRIVIAL(info) << "process_network_msg, device_cert_uninstalled";
6773 if (Slic3r::DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager()) {
6774 if (MachineObject* obj = dev->get_my_machine(dev_id)){
6775 obj->update_device_cert_state(false);
6776 }
6777 }
6778 return true;
6779 }
6780
6781 return false;
6782}
MachineObject * get_my_machine(std::string dev_id)
Definition DevManager.cpp:577
bool m_unsigned_plugin_warning_shown
Definition GUI_App.hpp:911
bool m_show_error_msgdlg
Definition GUI_App.hpp:374

References _L, Slic3r::MachineObject::get_dev_id(), Slic3r::DeviceManager::get_selected_machine(), getDeviceManager(), Slic3r::MachineObject::is_lan_mode_printer(), m_agent, m_show_error_msgdlg, m_unsigned_plugin_warning_shown, process_network_msg(), and Slic3r::GUI::DPIAware< P >::ShowModal().

Referenced by process_network_msg().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ push_notification()

void Slic3r::GUI::GUI_App::push_notification ( const MachineObject * obj,
wxString msg,
wxString title = wxEmptyString,
UserNotificationStyle style = UserNotificationStyle::UNS_NORMAL )
6970{
6971 if (this->is_enable_multi_machine())
6972 {
6973 if (m_device_manager && (obj != m_device_manager->get_selected_machine()))
6974 {
6975 return;
6976 }
6977 }
6978
6980 {
6981 if (m_info_dialog_content.empty())
6982 {
6983 wxCommandEvent* evt = new wxCommandEvent(EVT_SHOW_DIALOG);
6984 evt->SetString(msg);
6985 GUI::wxGetApp().QueueEvent(evt);
6987 }
6988 }
6990 {
6991 GUI::wxGetApp().CallAfter([msg, title]
6992 {
6993 GUI::MessageDialog msg_dlg(nullptr, msg, title, wxICON_WARNING | wxOK);
6994 msg_dlg.ShowModal();
6995 });
6996 }
6997}
#define style
Definition WipeTowerDialog.cpp:101
@ UNS_NORMAL
Definition UserNotification.hpp:8
@ UNS_WARNING_CONFIRM
Definition UserNotification.hpp:9

References is_enable_multi_machine(), m_device_manager, m_info_dialog_content, push_notification(), Slic3r::GUI::DPIAware< P >::ShowModal(), style, Slic3r::UNS_NORMAL, and Slic3r::UNS_WARNING_CONFIRM.

Referenced by push_notification().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ recreate_GUI()

void Slic3r::GUI::GUI_App::recreate_GUI ( const wxString & message)
4923{
4924 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "recreate_GUI enter";
4925 m_is_recreating_gui = true;
4926
4927 // The palette injects its translated strings once, at creation; drop the cached dialog so the
4928 // next open rebuilds it in the current locale (and can't outlive the old mainframe).
4929 if (m_speed_dial_dialog) {
4930 m_speed_dial_dialog->Destroy();
4931 m_speed_dial_dialog = nullptr;
4932 }
4933
4934 mainframe->shutdown();
4935 ProgressDialog dlg(msg_name, msg_name, 100, nullptr, wxPD_AUTO_HIDE);
4936 dlg.Pulse();
4937 dlg.Update(10, _L("Rebuild") + dots);
4938
4939 MainFrame *old_main_frame = mainframe;
4940 struct ClientData : wxClientData
4941 {
4942 ~ClientData() { release_window_pools(); }
4943 };
4944 old_main_frame->SetClientObject(new ClientData);
4945
4947 mainframe = new MainFrame();
4948 if (is_editor())
4949 // hide settings tabs after first Layout
4950 mainframe->select_tab(TAB_ID_PREPARE);
4951 // Propagate model objects to object list.
4952 sidebar().obj_list()->init();
4953 //sidebar().aux_list()->init_auxiliary();
4954 //mainframe->m_auxiliary->init_auxiliary();
4955 SetTopWindow(mainframe);
4956
4957 dlg.Update(30, _L("Rebuild") + dots);
4958 old_main_frame->Destroy();
4959
4960 dlg.Update(80, _L("Loading current presets") + dots);
4961 m_printhost_job_queue.reset(new PrintHostJobQueue(mainframe->printhost_queue_dlg()));
4963 mainframe->Show(true);
4964 //mainframe->refresh_plugin_tips();
4965
4966 dlg.Update(90, _L("Loading a mode view") + dots);
4967
4969 update_mode();
4970
4971 // clear previous hms query, so that the hms info can use different language
4972 if (hms_query) hms_query->clear_hms_info();
4973
4974 //BBS: trigger restore project logic here, and skip confirm
4975 plater_->trigger_restore_project(1);
4976 mainframe->prebuild_pages_when_idle();
4977
4978 // #ys_FIXME_delete_after_testing Do we still need this ?
4979// CallAfter([]() {
4980// // Run the config wizard, don't offer the "reset user profile" checkbox.
4981// config_wizard_startup(true);
4982// });
4983
4984
4986
4987 m_is_recreating_gui = false;
4988
4989 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "recreate_GUI exit";
4990}
void switch_window_pools()
Definition Field.cpp:859
void release_window_pools()
Definition Field.cpp:867

References _L, Slic3r::GUI::dots(), hms_query, is_editor(), load_current_presets(), m_is_recreating_gui, m_printhost_job_queue, m_speed_dial_dialog, mainframe, obj_list(), plater_, Slic3r::GUI::ProgressDialog::Pulse(), recreate_GUI(), Slic3r::GUI::release_window_pools(), sidebar(), Slic3r::GUI::switch_window_pools(), TAB_ID_PREPARE, Slic3r::GUI::ProgressDialog::Update(), update_mode(), and update_publish_status().

Referenced by open_preferences(), and recreate_GUI().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ refresh_plugins()

void Slic3r::GUI::GUI_App::refresh_plugins ( )
8946{
8947 // The metadata refresh blocks on disc discovery and a cloud round-trip, so run it on a worker
8948 // and report completion through the notification manager -- the speed dial needs no dialog.
8949 std::thread([]() {
8950 wxString error;
8951 bool unknown_error = false;
8952 try {
8953 refresh_plugin_metadata_blocking(/*fetch_cloud=*/true);
8954 } catch (const std::exception& ex) {
8955 error = from_u8(ex.what());
8956 } catch (...) {
8957 unknown_error = true; // translated in CallAfter: wx translation isn't safe off the UI thread
8958 }
8959 if (!wxTheApp)
8960 return;
8961 wxTheApp->CallAfter([error, unknown_error]() {
8962 if (wxGetApp().is_closing())
8963 return;
8964 Plater* plater = wxGetApp().plater();
8965 if (plater == nullptr)
8966 return;
8967 if (error.IsEmpty() && !unknown_error)
8968 plater->get_notification_manager()->push_notification(
8971 into_u8(_L("Plugins refreshed.")));
8972 else
8973 plater->get_notification_manager()->push_notification(
8976 into_u8(wxString::Format(_L("Failed to refresh plugins: %s"), unknown_error ? _L("Unknown error") : error)));
8977 });
8978 }).detach();
8979}
void refresh_plugin_metadata_blocking(bool fetch_cloud)
Definition PluginsDialog.cpp:433

References _L, Slic3r::GUI::CustomNotification, Slic3r::GUI::NotificationManager::ErrorNotificationLevel, Slic3r::GUI::from_u8(), Slic3r::GUI::into_u8(), is_closing(), plater(), Slic3r::GUI::refresh_plugin_metadata_blocking(), refresh_plugins(), and Slic3r::GUI::NotificationManager::RegularNotificationLevel.

Referenced by refresh_plugins().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ refresh_printer_agent_dropdown()

void Slic3r::GUI::GUI_App::refresh_printer_agent_dropdown ( )
private
4231{
4232 if (Tab* tab = get_tab(Preset::TYPE_PRINTER))
4233 {
4234 if (auto* printer_tab = dynamic_cast<TabPrinter*>(tab))
4235 printer_tab->refresh_printer_agent_dropdown();
4236 }
4237}

References get_tab(), refresh_printer_agent_dropdown(), and Slic3r::Preset::TYPE_PRINTER.

Referenced by init_plugin_gui_wiring(), and refresh_printer_agent_dropdown().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reload_settings()

bool Slic3r::GUI::GUI_App::reload_settings ( )
7000{
7001 if (preset_bundle && m_agent) {
7002 // Load user's personal presets
7003 std::map<std::string, std::map<std::string, std::string>> user_presets;
7004 int result = m_agent->get_user_presets(&user_presets);
7005 if (result != 0) {
7006 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": get_user_presets failed with code " << result << ", skipping sync";
7007 return false;
7008 }
7009 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " cloud user preset number is: " << user_presets.size();
7010 auto refresh_synced_ui = [this, user_presets = std::move(user_presets)]() mutable {
7011 if (is_closing() || !preset_bundle || !app_config || !mainframe)
7012 return;
7013
7014 // Snapshot each collection's edited config BEFORE any mutation.
7015 // load_pending_vendors() via apply_vendor_config() can call select_preset(0)
7016 // resetting all selections to defaults and overwriting m_edited_preset.
7017 // The cloud load_user_presets() can also trigger select_preset() via
7018 // remove_users_preset() and overwrite m_edited_preset.config via load_user_preset().
7019 struct PresetSnapshot { std::string name; DynamicPrintConfig config; bool dirty; };
7020 auto snapshot_collection = [](const PresetCollection& col) -> PresetSnapshot {
7021 auto& sel = col.get_selected_preset();
7022 auto& ed = col.get_edited_preset();
7023 return {sel.name, ed.config, sel.is_dirty};
7024 };
7025 PresetSnapshot print_snap = snapshot_collection(preset_bundle->prints);
7026 PresetSnapshot filament_snap = snapshot_collection(preset_bundle->filaments);
7027 PresetSnapshot printer_snap = snapshot_collection(preset_bundle->printers);
7028
7029 // Check the user presets for any system vendors that need to be installed
7030 for (auto data : user_presets) {
7033 }
7035
7036 preset_bundle->load_user_presets(*app_config, user_presets, ForwardCompatibilitySubstitutionRule::Enable);
7037 preset_bundle->save_user_presets(*app_config, get_delete_cache_presets());
7038
7039 // Re-apply any edited config that was wiped during vendor loading or sync.
7040 auto restore_snapshot = [](PresetCollection& col, const PresetSnapshot& snap, const char* label) {
7041 auto& ed = col.get_edited_preset();
7042 bool changed = !ed.config.equals(snap.config);
7043 BOOST_LOG_TRIVIAL(info) << "reload_settings restore " << label
7044 << ": snap_name=" << snap.name << " snap_dirty=" << snap.dirty
7045 << " current_name=" << ed.name << " changed=" << changed;
7046 if (!snap.dirty) return; // nothing to protect, let cloud updates stand
7047 Preset* p = col.find_preset(snap.name, false, true);
7048 if (p && p->name == snap.name) {
7049 BOOST_LOG_TRIVIAL(info) << "reload_settings RESTORING " << label
7050 << ": name=" << snap.name;
7051 // If the snapshot preset is not currently selected, re-select it first.
7052 if (col.get_selected_preset().name != snap.name)
7053 col.select_preset_by_name(snap.name, true);
7054 ed = col.get_edited_preset();
7055 ed.config = snap.config;
7056 col.get_selected_preset().is_dirty = snap.dirty;
7057 ed.is_dirty = snap.dirty;
7058 } else {
7059 BOOST_LOG_TRIVIAL(info) << "reload_settings restore " << label
7060 << ": preset not found name=" << snap.name;
7061 }
7062 };
7063 restore_snapshot(preset_bundle->prints, print_snap, "print");
7064 restore_snapshot(preset_bundle->filaments, filament_snap, "filament");
7065 restore_snapshot(preset_bundle->printers, printer_snap, "printer");
7066
7067 // Orca: settings changed, refresh ui to reflect the new preset values
7068 mainframe->update_side_preset_ui();
7069 for (auto tab : tabs_list) {
7070 tab->reload_config();
7071 tab->update_changed_ui();
7072 }
7073 if (plater_) {
7074 plater_->sidebar().update_all_preset_comboboxes();
7075 plater_->normalize_bed_types(false);
7076 }
7077 };
7079 refresh_synced_ui();
7080 else
7081 CallAfter(refresh_synced_ui);
7082 return true;
7083 }
7084 return false;
7085}
void add_pending_vendor_preset(const std::pair< std::string, std::map< std::string, std::string > > &preset_data)
Definition GUI_App.cpp:7384
bool check_preset_parent_available(const std::pair< std::string, std::map< std::string, std::string > > &preset_data)
Definition GUI_App.cpp:7365
void load_pending_vendors()
Definition GUI_App.cpp:7429
std::map< std::string, std::string > & get_delete_cache_presets()
Definition GUI_App.cpp:9429

References add_pending_vendor_preset(), app_config, check_preset_parent_available(), Slic3r::Preset::config, Slic3r::Enable, Slic3r::DynamicConfig::equals(), Slic3r::PresetCollection::find_preset(), get_delete_cache_presets(), Slic3r::PresetCollection::get_edited_preset(), Slic3r::PresetCollection::get_selected_preset(), is_closing(), Slic3r::Preset::is_dirty, Slic3r::is_main_thread_active(), load_pending_vendors(), m_agent, mainframe, Slic3r::Preset::name, plater_, preset_bundle, reload_settings(), Slic3r::PresetCollection::select_preset_by_name(), and tabs_list.

Referenced by reload_settings(), and start_sync_user_preset().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ removable_drive_manager()

RemovableDriveManager * Slic3r::GUI::GUI_App::removable_drive_manager ( )
inline
807{ return m_removable_drive_manager.get(); }

References m_removable_drive_manager.

Referenced by shutdown().

Here is the caller graph for this function:

◆ remove_mall_system_dialog()

void Slic3r::GUI::GUI_App::remove_mall_system_dialog ( )
9858{
9859 if (m_mall_publish_dialog != nullptr) {
9860 m_mall_publish_dialog->Destroy();
9861 delete m_mall_publish_dialog;
9862 }
9863}
ModelMallDialog * m_mall_publish_dialog
Definition GUI_App.hpp:755

References m_mall_publish_dialog, and remove_mall_system_dialog().

Referenced by remove_mall_system_dialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ remove_old_networking_plugins()

void Slic3r::GUI::GUI_App::remove_old_networking_plugins ( )
private
2208{
2209 std::string data_dir_str = data_dir();
2210 boost::filesystem::path data_dir_path(data_dir_str);
2211 auto plugin_folder = data_dir_path / "plugins";
2212 //auto plugin_folder = boost::filesystem::path(wxStandardPaths::Get().GetUserDataDir().ToUTF8().data()) / "plugins";
2213 if (boost::filesystem::exists(plugin_folder)) {
2214 BOOST_LOG_TRIVIAL(info) << "[remove_old_networking_plugins] remove the directory "<<plugin_folder.string();
2215 try {
2216 fs::remove_all(plugin_folder);
2217 } catch (...) {
2218 BOOST_LOG_TRIVIAL(error) << "Failed removing the plugins directory " << plugin_folder.string();
2219 }
2220 }
2221}

References Slic3r::data_dir().

Here is the call graph for this function:

◆ remove_ping_bind_dialog()

void Slic3r::GUI::GUI_App::remove_ping_bind_dialog ( )
9848{
9849 if (m_ping_code_binding_dialog != nullptr) {
9850 m_ping_code_binding_dialog->Destroy();
9851 delete m_mall_publish_dialog;
9853 }
9854}

References m_mall_publish_dialog, m_ping_code_binding_dialog, and remove_ping_bind_dialog().

Referenced by popup_ping_bind_dialog(), and remove_ping_bind_dialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ remove_user_presets()

void Slic3r::GUI::GUI_App::remove_user_presets ( )
7172{
7173 if (preset_bundle && m_agent) {
7174 preset_bundle->remove_users_preset(*app_config);
7175
7176 // Not remove user preset cache
7177 //std::string user_id = m_agent->get_user_id();
7178 //preset_bundle->remove_user_presets_directory(user_id);
7179
7180 //update ui
7181 mainframe->update_side_preset_ui();
7182 }
7183}

References app_config, m_agent, mainframe, preset_bundle, and remove_user_presets().

Referenced by on_user_login_handle(), remove_user_presets(), request_user_logout(), and restart_networking().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ request_cloud_web_session()

void Slic3r::GUI::GUI_App::request_cloud_web_session ( const std::string & state)
6013{
6014 if (state.empty())
6015 return;
6016
6017 // Only the newest request counts: a newer state supersedes any mint or login still in flight.
6018 m_cloud_handoff_state = state;
6019 const uint64_t gen = ++m_cloud_handoff_gen;
6020
6021 auto orca = get_orca_cloud_agent(m_agent);
6022 if (!orca || !orca->is_user_login()) {
6023 // Desktop signed out: open the desktop login dialog and stop here. On success
6024 // on_user_login_handle reloads the Start URL, which makes the page request again; on
6025 // cancel nothing happens (the guide's "on cancel, do nothing"). The newest state is
6026 // already stored, so a repeat request while the dialog is open is dropped rather than
6027 // stacking another dialog.
6028 if (!login_dlg || !login_dlg->IsShown())
6030 return;
6031 }
6032
6033 mint_cloud_web_session(state, gen);
6034}
ZUserLogin * login_dlg
Definition GUI_App.hpp:345
void mint_cloud_web_session(const std::string &state, uint64_t gen)
Definition GUI_App.cpp:6036

References Slic3r::GUI::get_orca_cloud_agent(), login_dlg, m_agent, m_cloud_handoff_gen, m_cloud_handoff_state, mint_cloud_web_session(), Slic3r::ORCA_CLOUD_PROVIDER(), request_cloud_web_session(), and request_login().

Referenced by request_cloud_web_session().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ request_login()

void Slic3r::GUI::GUI_App::request_login ( bool show_user_info = false,
const std::string & provider = ORCA_CLOUD_PROVIDER )
5289{
5290 ShowUserLogin(true, provider);
5291
5292 if (show_user_info) {
5293 CallAfter([this, provider] {
5294 get_login_info(provider);
5295 });
5296 }
5297}

References get_login_info(), request_login(), and ShowUserLogin().

Referenced by handle_web_request(), request_cloud_web_session(), and request_login().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ request_model_download()

void Slic3r::GUI::GUI_App::request_model_download ( wxString url)
5746{
5747 if (plater_) {
5748 plater_->request_model_download(url);
5749 }
5750}

References plater_, and request_model_download().

Referenced by request_model_download().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ request_new_version()

void Slic3r::GUI::GUI_App::request_new_version ( int by_user)
6786{
6787 wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_VERSION_ONLINE);
6788 evt->SetString(GUI::from_u8(version_info.version_str));
6789 evt->SetInt(by_user);
6790 GUI::wxGetApp().QueueEvent(evt);
6791}

References Slic3r::GUI::from_u8(), request_new_version(), and version_info.

Referenced by request_new_version().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ request_open_project()

void Slic3r::GUI::GUI_App::request_open_project ( std::string project_id)
5768{
5769 if (plater()->is_background_process_slicing()) {
5770 Slic3r::GUI::show_info(nullptr, _L("new or open project file is not allowed during the slicing process!"), _L("Open Project"));
5771 return;
5772 }
5773
5774 if (project_id == "<new>")
5775 plater()->new_project();
5776 else if (project_id.empty())
5777 plater()->load_project();
5778 else if (std::find_if_not(project_id.begin(), project_id.end(),
5779 [](char c) { return std::isdigit(c); }) == project_id.end())
5780 ;
5781 else if (boost::algorithm::starts_with(project_id, "http"))
5782 ;
5783 else
5784 CallAfter([this, project_id] { mainframe->open_recent_project(-1, wxString::FromUTF8(project_id)); });
5785}
int new_project(bool skip_confirm=false, bool silent=false, const wxString &project_name=wxString(), bool reload_presets=true)
Definition Plater.cpp:16054
void load_project(wxString const &filename="", wxString const &originfile="-")
Definition Plater.cpp:16144
void show_info(wxWindow *parent, const wxString &message, const wxString &title)
Definition GUI.cpp:316

References _L, mainframe, plater(), request_open_project(), and Slic3r::GUI::show_info().

Referenced by handle_web_request(), and request_open_project().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ request_project_download()

void Slic3r::GUI::GUI_App::request_project_download ( std::string project_id)
5761{
5762 if (!check_login()) return;
5763
5764 download_project(project_id);
5765}
bool check_login(const std::string &provider=ORCA_CLOUD_PROVIDER)
Definition GUI_App.cpp:5335
void download_project(std::string project_id)
Definition GUI_App.cpp:5753

References check_login(), download_project(), and request_project_download().

Referenced by handle_web_request(), and request_project_download().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ request_remove_project()

void Slic3r::GUI::GUI_App::request_remove_project ( std::string project_id)
5788{
5789 mainframe->remove_recent_project(-1, wxString::FromUTF8(project_id));
5790}

References mainframe, and request_remove_project().

Referenced by handle_web_request(), and request_remove_project().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ request_user_handle()

void Slic3r::GUI::GUI_App::request_user_handle ( int online_login = 0,
const std::string & provider = ORCA_CLOUD_PROVIDER )
5349{
5350 auto evt = new wxCommandEvent(EVT_USER_LOGIN_HANDLE);
5351 evt->SetInt(online_login);
5352 evt->SetString(wxString::FromUTF8(provider));
5353 wxQueueEvent(this, evt);
5354}

References request_user_handle().

Referenced by check_privacy_version(), on_check_privacy_update(), post_init(), request_user_handle(), and show_check_privacy_dlg().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ request_user_login()

void Slic3r::GUI::GUI_App::request_user_login ( int online_login = 0,
const std::string & provider = ORCA_CLOUD_PROVIDER )
5357{
5358 auto evt = new wxCommandEvent(EVT_USER_LOGIN);
5359 evt->SetInt(online_login);
5360 evt->SetString(wxString::FromUTF8(provider));
5361 wxQueueEvent(this, evt);
5362}

References request_user_login().

Referenced by handle_script_message(), and request_user_login().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ request_user_logout()

void Slic3r::GUI::GUI_App::request_user_logout ( const std::string & provider = ORCA_CLOUD_PROVIDER,
bool user_initiated = false )
5374{
5375 if (m_agent && m_agent->is_user_login(provider)) {
5376 m_agent->user_logout(true, provider);
5377
5378 if (provider == get_printer_cloud_provider()) {
5379 m_agent->set_user_selected_machine("");
5380 if (m_device_manager) {
5381 m_device_manager->clean_user_info(true);
5382 }
5383 }
5384
5385 if (provider == ORCA_CLOUD_PROVIDER) {
5386 // Invalidate any handoff still in flight, so a token minted for the signed-out
5387 // account is never loaded into the pane.
5389 m_cloud_handoff_state.clear();
5390
5391 // An explicit user sign-out also ends the webview's own cloud session (guide §8).
5392 // A session the desktop lost on its own must NOT do this: a 2FA user would otherwise
5393 // loop through the code prompt on every desktop re-login.
5394 if (user_initiated) {
5395 if (auto orca = get_orca_cloud_agent(m_agent)) {
5396 if (WebViewPanel* home = WebViewPanel::if_built())
5397 home->cloud_signed_out(from_u8(orca->build_web_session_signout_url()));
5398 }
5399 }
5400
5401 /* delete old user settings */
5402 bool transfer_preset_changes = false;
5403 wxString header = _L("Some presets are modified.") + "\n" +
5404 _L("You can keep the modified presets for the new project, discard, or save changes as new presets.");
5405 wxGetApp().check_and_keep_current_preset_changes(_L("User logged out"), header, ActionButtons::KEEP | ActionButtons::SAVE, &transfer_preset_changes);
5406
5413 mainframe->update_side_preset_ui();
5414
5415 // keep this here. refresh_from_catalog is meant to update the dialog UI.
5416 if (m_plugins_dlg)
5417 m_plugins_dlg->update_plugin_dialog_ui();
5418
5419 GUI::wxGetApp().stop_sync_user_preset();
5420 }
5421
5422 post_logout_to_webview(provider);
5423 }
5424}
void post_logout_to_webview(const std::string &provider)
Definition GUI_App.cpp:5364
void unload_cloud_plugins()
Definition PluginManager.cpp:1135
void clear_cloud_plugin_metadata()
Definition PluginManager.cpp:1589
@ KEEP
Definition UnsavedChangesDialog.hpp:252

References _L, Slic3r::PluginManager::clear_cloud_plugin_metadata(), DEFAULT_USER_FOLDER_NAME, Slic3r::Enable, enable_user_preset_folder(), Slic3r::GUI::from_u8(), Slic3r::GUI::get_orca_cloud_agent(), get_printer_cloud_provider(), Slic3r::GUI::LazyInstance< WebViewPanel >::if_built(), Slic3r::PluginManager::instance(), Slic3r::GUI::KEEP, m_agent, m_cloud_handoff_gen, m_cloud_handoff_state, m_device_manager, m_plugins_dlg, mainframe, Slic3r::ORCA_CLOUD_PROVIDER(), post_logout_to_webview(), preset_bundle, remove_user_presets(), request_user_logout(), Slic3r::GUI::SAVE, Slic3r::PluginManager::set_cloud_user(), and Slic3r::PluginManager::unload_cloud_plugins().

Referenced by handle_web_request(), on_http_error(), on_stealth_mode_enter(), and request_user_logout().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ request_user_unbind()

int Slic3r::GUI::GUI_App::request_user_unbind ( std::string dev_id,
const std::string & provider = ORCA_CLOUD_PROVIDER )
5427{
5428 int result = -1;
5429 if (m_agent) {
5430 result = m_agent->unbind(dev_id);
5431 BOOST_LOG_TRIVIAL(info) << "request_user_unbind, dev_id = " << dev_id << ", result = " << result;
5432 return result;
5433 }
5434 return result;
5435}

References m_agent, and request_user_unbind().

Referenced by request_user_unbind().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reset_to_active()

void Slic3r::GUI::GUI_App::reset_to_active ( )
6188{
6189 last_active_point = std::chrono::system_clock::now();
6190}

References last_active_point, and reset_to_active().

Referenced by GUI_App(), and reset_to_active().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reset_unsigned_plugin_warning()

void Slic3r::GUI::GUI_App::reset_unsigned_plugin_warning ( )
inline

◆ resolve_printer_agent_id()

std::string Slic3r::GUI::GUI_App::resolve_printer_agent_id ( const std::string & stored_id) const
4263{
4264 if (!stored_id.empty())
4265 return stored_id;
4267}
static constexpr char ORCA_PRINTER_AGENT_ID[]
Definition NetworkAgentFactory.hpp:19

References Slic3r::BBL_PRINTER_AGENT_ID, Slic3r::ORCA_PRINTER_AGENT_ID, preset_bundle, and resolve_printer_agent_id().

Referenced by canonical_printer_agent_id(), get_printer_cloud_provider(), resolve_printer_agent_id(), switch_printer_agent(), and switch_printer_agent_if_pending().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ restart_networking()

void Slic3r::GUI::GUI_App::restart_networking ( )
1861{
1862 BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(" enter, mainframe %1%")%mainframe;
1863 on_init_network(true);
1865 if(m_agent) {
1867 m_agent->set_on_ssdp_msg_fn(
1868 [this](std::string json_str) {
1869 if (!is_closing() && m_device_manager)
1870 m_device_manager->on_machine_alive(json_str);
1871 }
1872 );
1873 m_agent->set_on_http_error_fn([this](CloudEvent event, unsigned int status, std::string body) {
1874 this->handle_http_error(status, body, event.provider);
1875 });
1876 // on_init_network() rebuilt m_agent with a null printer agent, so calling
1877 // m_agent->start_discovery() directly would no-op (NetworkAgent::start_discovery
1878 // returns false when m_printer_agent is null). Re-establish the printer agent for the
1879 // active preset first - switch_printer_agent() installs it and then starts discovery,
1880 // mirroring startup - otherwise LAN discovery stays dead after a plugin hot reload
1881 // until the user next changes a preset/tab.
1883 if (mainframe)
1884 mainframe->refresh_plugin_tips();
1885 if (plater_)
1886 plater_->get_notification_manager()->bbl_close_plugin_install_notification();
1887
1888 if (m_agent->is_user_login()) {
1891 preset_bundle->load_user_presets(m_agent->get_user_id(), ForwardCompatibilitySubstitutionRule::Enable);
1892 mainframe->update_side_preset_ui();
1893 }
1894
1895 if (app_config->get("sync_user_preset") == "true") {
1897 }
1898 // if (mainframe && this->app_config->get("staff_pick_switch") == "true") {
1899 // if (mainframe->m_webview) { mainframe->m_webview->SendDesignStaffpick(has_model_mall()); }
1900 // }
1901 }
1902 BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(" exit, m_agent=%1%")%m_agent;
1903}
void switch_printer_agent()
Definition GUI_App.cpp:4274
static void reset()
Definition PrinterFileSystem.cpp:1895

References app_config, Slic3r::Enable, enable_user_preset_folder(), handle_http_error(), init_networking_callbacks(), is_closing(), m_agent, m_device_manager, mainframe, on_init_network(), plater_, preset_bundle, Slic3r::CloudEvent::provider, remove_user_presets(), StaticBambuLib::reset(), start_sync_user_preset(), and switch_printer_agent().

Referenced by hot_reload_network_plugin().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ restart_sync_user_preset()

void Slic3r::GUI::GUI_App::restart_sync_user_preset ( )
8236{
8237 // A manual sync's progress dialog is already on screen — ignore repeat triggers so a
8238 // second modal dialog can never stack. This matters most offline: each attempt blocks
8239 // on a long HTTP timeout and can't be cancelled mid-request, and on macOS the global
8240 // menu bar stays clickable even while the dialog disables the main window, so without
8241 // this guard repeated clicks pile up modal dialogs and wedge the UI (force-quit only).
8243 return;
8244
8245 if (!m_user_sync_token) {
8246 // No sync running. If a restart helper is already in flight it will
8247 // start the new sync once the old thread is joined — don't race it.
8250 return;
8251 }
8252
8253 // Resetting the token signals the old thread to stop (cancelFn checks
8254 // t.expired(), so it exits after its current HTTP request completes).
8255 // A helper thread joins the old thread off the UI thread — no freeze —
8256 // then starts the new sync via CallAfter once the old one is fully done.
8257 m_user_sync_token.reset();
8259
8260 auto old_thread = std::move(m_sync_update_thread);
8261
8262 std::thread([this, old_thread = std::move(old_thread)]() mutable {
8263 if (old_thread.joinable())
8264 old_thread.join();
8265 m_restart_sync_pending = false;
8266 if (!is_closing())
8267 CallAfter([this]() {
8268 if (!is_closing())
8270 });
8271 }).detach();
8272}
std::atomic< bool > m_sync_user_preset_dlg_active
Definition GUI_App.hpp:356
std::atomic< bool > m_restart_sync_pending
Definition GUI_App.hpp:355

References is_closing(), m_restart_sync_pending, m_sync_update_thread, m_sync_user_preset_dlg_active, m_user_sync_token, restart_sync_user_preset(), and start_sync_user_preset().

Referenced by on_http_error(), and restart_sync_user_preset().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ run_script()

void Slic3r::GUI::GUI_App::run_script ( wxString js)
9866{
9867 if (mainframe)
9868 return mainframe->RunScript(js);
9869}

References mainframe, and run_script().

Referenced by run_script().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ run_wizard()

bool Slic3r::GUI::GUI_App::run_wizard ( ConfigWizard::RunReason reason,
ConfigWizard::StartPage start_page = ConfigWizard::SP_WELCOME )
9966{
9967 wxCHECK_MSG(mainframe != nullptr, false, "Internal error: Main frame not created / null");
9968
9969#ifdef __APPLE__
9971 BOOST_LOG_TRIVIAL(info) << "run_wizard: Script handler is being added, delaying wizard creation";
9972 auto timer = new wxTimer();
9973 timer->Bind(wxEVT_TIMER, [this, reason, start_page, timer](wxTimerEvent &) {
9974 timer->Stop();
9975 run_wizard(reason, start_page);
9976 delete timer;
9977 });
9978 timer->StartOnce(200);
9979
9980 return true;
9981 }
9982#endif
9983
9984 //if (reason == ConfigWizard::RR_USER) {
9985 // //TODO: turn off it currently, maybe need to turn on in the future
9986 // if (preset_updater->config_update(app_config->orig_version(), PresetUpdater::UpdateParams::FORCED_BEFORE_WIZARD) == PresetUpdater::R_ALL_CANCELED)
9987 // return false;
9988 //}
9989
9990 //auto wizard_t = new ConfigWizard(mainframe);
9991 //const bool res = wizard_t->run(reason, start_page);
9992
9993 std::string strFinish = wxGetApp().app_config->get("firstguide", "finish");
9994 long pStyle = wxCAPTION | wxCLOSE_BOX | wxSYSTEM_MENU;
9995 if (strFinish == "false" || strFinish.empty())
9996 pStyle = wxCAPTION | wxTAB_TRAVERSAL;
9997
9998 GuideFrame wizard(this, pStyle);
9999 auto page = start_page == ConfigWizard::SP_WELCOME ? GuideFrame::BBL_WELCOME :
10003 wizard.SetStartPage(page);
10004 bool res = wizard.run();
10005
10006 if (res) {
10009 mainframe->refresh_plugin_tips();
10010 // BBS: remove SLA related message
10011 }
10012
10013 return res;
10014}
@ SP_PRINTERS
Definition ConfigWizard.hpp:33
@ SP_FILAMENTS
Definition ConfigWizard.hpp:34
@ SP_WELCOME
Definition ConfigWizard.hpp:32
bool is_adding_script_handler()
Definition GUI_App.hpp:774
@ BBL_FILAMENT_ONLY
Definition WebGuideDialog.hpp:72
@ BBL_WELCOME
Definition WebGuideDialog.hpp:68
@ BBL_MODELS_ONLY
Definition WebGuideDialog.hpp:73
@ BBL_MODELS
Definition WebGuideDialog.hpp:70

References Slic3r::GUI::GuideFrame::BBL_FILAMENT_ONLY, Slic3r::GUI::GuideFrame::BBL_MODELS, Slic3r::GUI::GuideFrame::BBL_MODELS_ONLY, Slic3r::GUI::GuideFrame::BBL_WELCOME, is_adding_script_handler(), load_current_presets(), mainframe, Slic3r::GUI::GuideFrame::run(), run_wizard(), Slic3r::GUI::GuideFrame::SetStartPage(), Slic3r::GUI::ConfigWizard::SP_FILAMENTS, Slic3r::GUI::ConfigWizard::SP_PRINTERS, Slic3r::GUI::ConfigWizard::SP_WELCOME, and update_publish_status().

Referenced by config_wizard_startup(), and run_wizard().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ save_mode()

void Slic3r::GUI::GUI_App::save_mode ( const int mode)
8770{
8771 const auto saved_mode = mode == comExpert ? comExpert :
8772 mode == comAdvanced ? comAdvanced :
8773 mode == comSimple ? comSimple :
8775 app_config->set("user_mode", saved_mode_to_string(saved_mode));
8776 update_mode();
8777}
@ comAdvanced
Definition Config.hpp:223
@ comExpert
Definition Config.hpp:224

References app_config, Slic3r::comAdvanced, Slic3r::comExpert, Slic3r::comSimple, get_saved_mode(), save_mode(), and update_mode().

Referenced by save_mode(), and set_mode().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ scan_orphaned_info_files()

void Slic3r::GUI::GUI_App::scan_orphaned_info_files ( )
9511{
9512 // Get user preset directory
9513 std::string user_sub_folder = app_config->get("preset_folder");
9514 if (user_sub_folder.empty())
9515 user_sub_folder = DEFAULT_USER_FOLDER_NAME;
9516 const std::string dir_user_presets = data_dir() + "/" + PRESET_USER_DIR + "/" + user_sub_folder;
9517
9518 // Scan for orphaned .info files in each preset type directory
9519 std::vector<std::string> preset_types = {PRESET_PRINT_NAME, PRESET_FILAMENT_NAME, PRESET_PRINTER_NAME};
9520
9521 for (const std::string& type : preset_types) {
9522 fs::path type_dir = fs::path(dir_user_presets) / type;
9523 if (!fs::exists(type_dir))
9524 continue;
9525
9526 // Iterate through all .info files. Use the error_code-based iterator so a transient
9527 // directory-read failure (e.g. macOS readdir returning ENOTSUP) is logged and skipped
9528 // instead of throwing an uncaught exception that would terminate the app from the
9529 // background sync thread this runs on.
9530 boost::system::error_code ec;
9531 for (boost::filesystem::directory_iterator it(type_dir, ec), end; !ec && it != end; it.increment(ec)) {
9532 const auto& entry = *it;
9533 if (entry.path().extension() != ".info")
9534 continue;
9535
9536 fs::path info_file = entry.path();
9537 fs::path preset_file = info_file;
9538 preset_file.replace_extension(".json");
9539
9540 // If .json doesn't exist, .info is orphaned. Read under the lock, so a
9541 // remove_files() in another instance is seen whole or not at all; the
9542 // delete queue's own mutex is taken after the lock is released.
9543 std::string setting_id;
9544 {
9545 InstanceLock instance_lock(user_presets_lock_path());
9546 if (!fs::exists(preset_file))
9547 setting_id = extract_setting_id_from_info(info_file.string());
9548 }
9549 if (!setting_id.empty()) {
9550 // Add to need_delete_presets
9551 delete_preset_from_cloud(setting_id, info_file.string());
9552 BOOST_LOG_TRIVIAL(info) << "Found orphaned .info file on startup: " << info_file.string();
9553 }
9554 }
9555 if (ec)
9556 BOOST_LOG_TRIVIAL(warning) << "scan_orphaned_info_files: failed to scan " << type_dir.string() << ": " << ec.message();
9557 }
9558}
#define PRESET_PRINTER_NAME
Definition Preset.hpp:35
#define PRESET_PRINT_NAME
Definition Preset.hpp:34
#define PRESET_FILAMENT_NAME
Definition Preset.hpp:33
static std::string extract_setting_id_from_info(const std::string &info_file_path)
Definition GUI_App.cpp:9487
void delete_preset_from_cloud(std::string setting_id, std::string preset_file_path)
Definition GUI_App.cpp:9460

References app_config, Slic3r::data_dir(), DEFAULT_USER_FOLDER_NAME, delete_preset_from_cloud(), extract_setting_id_from_info(), PRESET_FILAMENT_NAME, PRESET_PRINT_NAME, PRESET_PRINTER_NAME, PRESET_USER_DIR, scan_orphaned_info_files(), and Slic3r::user_presets_lock_path().

Referenced by scan_orphaned_info_files(), and start_sync_user_preset().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ select_machine()

void Slic3r::GUI::GUI_App::select_machine ( const std::string & agent_id)
private
4370{
4371 // Skip for BBL agent for now - uses its own device discovery/selection
4372 // Orca todo: revisit in future if we want to support auto-switching for BBL printers
4373 if (agent_id == BBL_PRINTER_AGENT_ID) {
4374 return;
4375 }
4376
4378 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": no device manager or preset bundle";
4379 return;
4380 }
4381
4382 // Get config source (preset or physical printer)
4383 const auto& preset = preset_bundle->printers.get_edited_preset();
4384 const DynamicPrintConfig* host_cfg = &preset.config;
4385
4386 // Hands the machine to the Device tab's full selection flow (UI updates, callbacks, etc.).
4387 auto select_dev = [this](const std::string& dev_id) {
4388 if (MonitorPanel* monitor = MonitorPanel::if_built()) {
4389 monitor->select_machine(dev_id);
4390 BOOST_LOG_TRIVIAL(info) << "GUI_App::select_machine" << ": triggered select_machine for dev_id=" << dev_id;
4391 } else if (m_device_manager->set_selected_machine(dev_id)) {
4392 // The Device tab's own state is set when the tab is built.
4393 MonitorPanel::on_machine_selected(m_device_manager->get_selected_machine());
4394 BOOST_LOG_TRIVIAL(info) << "GUI_App::select_machine" << ": set_selected_machine dev_id=" << dev_id;
4395 }
4396 };
4397
4398 std::string print_host = host_cfg->opt_string("print_host");
4399 if (print_host.empty()) {
4400 // Orca: a printer bound from the Device tab is kept as a device of the agent rather than in
4401 // the preset's print_host. Select it when it is the agent's only one, as
4402 // MainFrame::load_printer_url() does; otherwise nothing is selected until the print dialog
4403 // picks it, and filament sync has no printer to read from.
4404 const auto machines = m_device_manager->get_my_machine_list(agent_id);
4405 if (machines.size() == 1 && machines.begin()->second)
4406 select_dev(machines.begin()->second->get_dev_id());
4407 return;
4408 }
4409 std::string port = host_cfg->opt_string("printhost_port");
4410 std::string access_code = host_cfg->opt_string("printhost_apikey");
4411 if (access_code.empty() && agent_id != MOONRAKER_PRINTER_AGENT_ID)
4412 access_code = "88888888";
4413
4414 // Generate dev_id from host and port
4415 std::string dev_id = MachineObject::dev_id_from_address(print_host, port);
4416
4417 // Check if already exists by dev_id
4418 MachineObject* existing = m_device_manager->get_local_machine(dev_id);
4419
4420 // If not found by dev_id, search by full_addr
4421 if (!existing) {
4422 auto local_machines = m_device_manager->get_local_machinelist();
4423 for (auto& [id, machine] : local_machines) {
4424 if (machine && machine->get_dev_ip() == dev_id) {
4425 existing = machine;
4426 break;
4427 }
4428 }
4429 }
4430
4431 // If machine doesn't exist, create it first
4432 if (!existing) {
4433 BBLocalMachine machine;
4434 machine.dev_id = dev_id;
4435 // We use dev_id as dev_ip to store the address (host:port)
4436 machine.dev_ip = dev_id;
4437 machine.dev_name = dev_id;
4438 machine.printer_type = preset.config.opt_string("printer_model");
4439
4440 existing = m_device_manager->insert_local_device(
4441 machine, "lan", "free", "", access_code);
4442
4443 if (!existing) {
4444 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": failed to create machine dev_id=" << dev_id;
4445 return;
4446 }
4447 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": created new machine dev_id=" << dev_id;
4448 } else if (agent_id == MOONRAKER_PRINTER_AGENT_ID && existing->printer_agent_id == agent_id &&
4449 (!existing->has_access_right() || existing->get_access_code() != access_code)) {
4450 existing->set_access_code(access_code);
4451 }
4452 existing->local_use_ssl = boost::istarts_with(print_host, "https://");
4453 select_dev(dev_id);
4454}
static void on_machine_selected(MachineObject *obj)
Definition Monitor.cpp:337
static std::string dev_id_from_address(const std::string &host, const std::string &port="")
Definition DeviceManager.cpp:495
static constexpr char MOONRAKER_PRINTER_AGENT_ID[]
Definition NetworkAgentFactory.hpp:21

References Slic3r::BBL_PRINTER_AGENT_ID, Slic3r::BBLocalMachine::dev_id, Slic3r::MachineObject::dev_id_from_address(), Slic3r::BBLocalMachine::dev_ip, Slic3r::BBLocalMachine::dev_name, Slic3r::MachineObject::get_access_code(), Slic3r::MachineObject::has_access_right(), Slic3r::GUI::LazyInstance< MonitorPanel >::if_built(), Slic3r::MachineObject::local_use_ssl, m_device_manager, Slic3r::MOONRAKER_PRINTER_AGENT_ID, Slic3r::GUI::MonitorPanel::on_machine_selected(), Slic3r::DynamicConfig::opt_string(), preset_bundle, Slic3r::MachineObject::printer_agent_id, Slic3r::BBLocalMachine::printer_type, select_machine(), and Slic3r::MachineObject::set_access_code().

Referenced by select_machine(), and switch_printer_agent().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_adding_script_handler()

void Slic3r::GUI::GUI_App::set_adding_script_handler ( bool status)
inline
775{ m_adding_script_handler = status; }

References m_adding_script_handler.

◆ set_auto_toolbar_icon_scale()

void Slic3r::GUI::GUI_App::set_auto_toolbar_icon_scale ( float scale) const
4892{
4893#ifdef __APPLE__
4894 const float icon_sc = 1.0f; // for Retina display will be used its own scale
4895#else
4896 const float icon_sc = m_em_unit * 0.1f;
4897#endif // __APPLE__
4898
4899 long int_val = std::min(int(std::lround(scale / icon_sc * 100)), 100);
4900 std::string val = std::to_string(int_val);
4901
4902 app_config->set("toolkit_size", val);
4903}
int scale(const int val)
Definition WipeTowerDialog.cpp:58

References app_config, m_em_unit, scale(), and set_auto_toolbar_icon_scale().

Referenced by set_auto_toolbar_icon_scale().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_closing()

void Slic3r::GUI::GUI_App::set_closing ( bool closing)
inline
437{ m_is_closing.store(closing, std::memory_order_release); }
Slic3r::Polygons closing(const Slic3r::Polygons &polygons, const float delta1, const float delta2, JoinType joinType, double miterLimit)
Definition ClipperUtils.cpp:670

References Slic3r::closing(), and m_is_closing.

Referenced by shutdown().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_download_model_name()

void Slic3r::GUI::GUI_App::set_download_model_name ( std::string name)
inline

◆ set_download_model_url()

void Slic3r::GUI::GUI_App::set_download_model_url ( std::string url)
inline

◆ set_instance_hash()

void Slic3r::GUI::GUI_App::set_instance_hash ( const size_t hash)
inline
812{ m_instance_hash_int = hash; m_instance_hash_string = std::to_string(hash); }

References m_instance_hash_int, and m_instance_hash_string.

◆ set_label_clr_modified()

void Slic3r::GUI::GUI_App::set_label_clr_modified ( const wxColour & clr)
4784{
4785 return;
4786 //BBS
4787 /*
4788 if (m_color_label_modified == clr)
4789 return;
4790 m_color_label_modified = clr;
4791 const std::string str = encode_color(ColorRGB(clr.Red(), clr.Green(), clr.Blue()));
4792 app_config->save();
4793 */
4794}

References set_label_clr_modified().

Referenced by set_label_clr_modified().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_label_clr_sys()

void Slic3r::GUI::GUI_App::set_label_clr_sys ( const wxColour & clr)
4797{
4798 return;
4799 //BBS
4800 /*
4801 if (m_color_label_sys == clr)
4802 return;
4803 m_color_label_sys = clr;
4804 const std::string str = encode_color(ColorRGB(clr.Red(), clr.Green(), clr.Blue()));
4805 app_config->save();
4806 */
4807}

References set_label_clr_sys().

Referenced by set_label_clr_sys().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_live_printer_agent()

void Slic3r::GUI::GUI_App::set_live_printer_agent ( std::shared_ptr< IPrinterAgent > agent)
private
4240{
4241 if (!m_agent)
4242 return;
4243
4244 // why: tearing down the old machine selection is only ever the prefix of setting the live
4245 // agent (to a new one, or to null when the selection is missing) - so it lives here, not as
4246 // a standalone helper. Pass nullptr to clear the selection.
4247 if (DeviceManager* dev = getDeviceManager())
4248 {
4249 dev->set_selected_machine(""); // why: empty id disconnects and deselects the current machine
4250 m_agent->set_user_selected_machine("");
4251 // note: belt-and-suspenders (precedent: DeviceManagerRefresher::on_timer)
4252 dev->OnSelectedMachineLost(); // why: clear stale sidebar sync-status / AMS
4253 // why: retain agent-owned LAN discoveries so agents without automatic discovery (for
4254 // example the Moonraker-based Qidi/Snapmaker agents) can reuse them after a switch.
4255 dev->clear_other_devices();
4256 }
4257
4258 m_agent->set_printer_agent(agent);
4260}
void update_all_preset_comboboxes()
Definition Plater.cpp:3795

References getDeviceManager(), m_agent, set_live_printer_agent(), and sidebar().

Referenced by set_live_printer_agent(), and switch_printer_agent().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_mode()

void Slic3r::GUI::GUI_App::set_mode ( ConfigOptionMode mode)
8780{
8781 const bool was_developer = app_config->get_bool("developer_mode");
8782 if (was_developer)
8783 app_config->set_bool("developer_mode", false);
8784 save_mode(mode);
8785 if (was_developer)
8786 app_config->save();
8787}
void save_mode(const int mode)
Definition GUI_App.cpp:8769

References app_config, save_mode(), and set_mode().

Referenced by set_mode().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_side_menu_popup_status()

void Slic3r::GUI::GUI_App::set_side_menu_popup_status ( bool status)
4815{
4816 m_side_popup_status = status;
4817}

References m_side_popup_status, and set_side_menu_popup_status().

Referenced by set_side_menu_popup_status().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_skip_version()

void Slic3r::GUI::GUI_App::set_skip_version ( bool skip = true)
6800{
6801 BOOST_LOG_TRIVIAL(info) << "set_skip_version, skip = " << skip << ", version = " <<version_info.version_str;
6802 if (skip) {
6803 app_config->set("skip_version", version_info.version_str);
6804 }else {
6805 app_config->set("skip_version", "");
6806 }
6807}

References app_config, set_skip_version(), and version_info.

Referenced by set_skip_version().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ shortcuts()

ShortcutRegistry & Slic3r::GUI::GUI_App::shortcuts ( )
inline
817{ return *m_shortcuts; }

References m_shortcuts.

◆ show_3d_navigator()

bool Slic3r::GUI::GUI_App::show_3d_navigator ( ) const
inline
445{ return app_config->get_bool("show_3d_navigator"); }

References app_config.

Referenced by toggle_show_3d_navigator().

Here is the caller graph for this function:

◆ show_canvas_zoom_button()

bool Slic3r::GUI::GUI_App::show_canvas_zoom_button ( ) const
inline
453{ return app_config->get_bool("show_canvas_zoom_button"); }

References app_config.

Referenced by toggle_canvas_zoom_button().

Here is the caller graph for this function:

◆ show_center_of_mass()

bool Slic3r::GUI::GUI_App::show_center_of_mass ( ) const
inline
459{ return app_config->get_bool("show_center_of_mass"); }

References app_config.

Referenced by toggle_show_center_of_mass().

Here is the caller graph for this function:

◆ show_check_privacy_dlg()

void Slic3r::GUI::GUI_App::show_check_privacy_dlg ( wxCommandEvent & evt)
6810{
6811 int online_login = evt.GetInt();
6812 std::string provider = evt.GetString().ToStdString();
6813 if (provider.empty()) provider = ORCA_CLOUD_PROVIDER;
6814 PrivacyUpdateDialog privacy_dlg(this->mainframe, wxID_ANY, _L("Privacy Policy Update"));
6815 privacy_dlg.Bind(EVT_PRIVACY_UPDATE_CONFIRM, [this, online_login, provider](wxCommandEvent &e) {
6816 app_config->set("privacy_version", privacy_version_info.version_str);
6817 app_config->set_bool("privacy_update_checked", true);
6818 request_user_handle(online_login, provider);
6819 });
6820 privacy_dlg.Bind(EVT_PRIVACY_UPDATE_CANCEL, [this, provider](wxCommandEvent &e) {
6821 app_config->set_bool("privacy_update_checked", false);
6822 if (m_agent) {
6823 BOOST_LOG_TRIVIAL(info) << "logout: Privacy update dialog cancelled.";
6824 m_agent->user_logout(false, provider);
6825 post_logout_to_webview(provider);
6826 }
6827 });
6828
6829 privacy_dlg.set_text(privacy_version_info.description);
6830 privacy_dlg.on_show();
6831}

References _L, app_config, m_agent, mainframe, Slic3r::GUI::PrivacyUpdateDialog::on_show(), Slic3r::ORCA_CLOUD_PROVIDER(), post_logout_to_webview(), privacy_version_info, request_user_handle(), Slic3r::GUI::PrivacyUpdateDialog::set_text(), and show_check_privacy_dlg().

Referenced by on_init_inner(), and show_check_privacy_dlg().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_desktop_integration_dialog()

void Slic3r::GUI::GUI_App::show_desktop_integration_dialog ( )
10017{
10018#ifdef __linux__
10019 //wxCHECK_MSG(mainframe != nullptr, false, "Internal error: Main frame not created / null");
10020 DesktopIntegrationDialog dialog(mainframe);
10021 dialog.ShowModal();
10022#endif //__linux__
10023}

References mainframe, and show_desktop_integration_dialog().

Referenced by show_desktop_integration_dialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_dialog()

void Slic3r::GUI::GUI_App::show_dialog ( wxString msg)
6960{
6961 if (m_info_dialog_content.empty()) {
6962 wxCommandEvent* evt = new wxCommandEvent(EVT_SHOW_DIALOG);
6963 evt->SetString(msg);
6964 GUI::wxGetApp().QueueEvent(evt);
6966 }
6967}

References m_info_dialog_content, and show_dialog().

Referenced by show_dialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_gcode_window()

bool Slic3r::GUI::GUI_App::show_gcode_window ( ) const
inline
442{ return m_show_gcode_window; }

References m_show_gcode_window.

◆ show_ip_address_enter_dialog()

void Slic3r::GUI::GUI_App::show_ip_address_enter_dialog ( wxString title = wxEmptyString)
8833{
8834 auto evt = new wxCommandEvent(EVT_SHOW_IP_DIALOG);
8835 evt->SetString(title);
8836 evt->SetInt(-1);
8837 wxQueueEvent(this, evt);
8838}

References show_ip_address_enter_dialog().

Referenced by show_ip_address_enter_dialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_ip_address_enter_dialog_handler()

void Slic3r::GUI::GUI_App::show_ip_address_enter_dialog_handler ( wxCommandEvent & evt)
8877{
8878 wxString title = evt.GetString();
8879 int mode = evt.GetInt();
8880 show_modal_ip_address_enter_dialog(mode == -1?false:true, title);
8881}
bool show_modal_ip_address_enter_dialog(bool input_sn, wxString title=wxEmptyString)
Definition GUI_App.cpp:8840

References show_ip_address_enter_dialog_handler(), and show_modal_ip_address_enter_dialog().

Referenced by on_init_inner(), and show_ip_address_enter_dialog_handler().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_message_box()

void Slic3r::GUI::GUI_App::show_message_box ( std::string msg)
inline
402{ wxMessageBox(msg); }

◆ show_modal_ip_address_enter_dialog()

bool Slic3r::GUI::GUI_App::show_modal_ip_address_enter_dialog ( bool input_sn,
wxString title = wxEmptyString )
8841{
8842 DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
8843 if (!dev) return false;
8844 if (!dev->get_selected_machine()) return false;
8845 auto obj = dev->get_selected_machine();
8846
8847 InputIpAddressDialog dlg(nullptr);
8848 dlg.m_need_input_sn = input_sn;
8849 dlg.set_machine_obj(obj);
8850 if (!title.empty()) dlg.update_title(title);
8851
8852 dlg.Bind(EVT_ENTER_IP_ADDRESS, [obj](wxCommandEvent& e) {
8853 auto selection_data_arr = wxSplit(e.GetString().ToStdString(), '|');
8854
8855 if (selection_data_arr.size() == 2) {
8856 auto ip_address = selection_data_arr[0];
8857 auto access_code = selection_data_arr[1];
8858
8859 BOOST_LOG_TRIVIAL(info) << "User enter IP address is " << ip_address;
8860 if (!ip_address.empty()) {
8861 wxGetApp().app_config->set_str("ip_address", obj->get_dev_id(), ip_address.ToStdString());
8862 wxGetApp().app_config->save();
8863
8864 obj->set_dev_ip(ip_address.ToStdString());
8865 obj->set_access_code(access_code.ToStdString());
8866 }
8867 }
8868 });
8869
8870 if (dlg.ShowModal() == wxID_YES) {
8871 return true;
8872 }
8873 return false;
8874}

References Slic3r::DeviceManager::get_selected_machine(), Slic3r::GUI::InputIpAddressDialog::m_need_input_sn, Slic3r::GUI::InputIpAddressDialog::set_machine_obj(), show_modal_ip_address_enter_dialog(), Slic3r::GUI::DPIAware< P >::ShowModal(), and Slic3r::GUI::InputIpAddressDialog::update_title().

Referenced by show_ip_address_enter_dialog_handler(), and show_modal_ip_address_enter_dialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_network_plugin_download_dialog()

void Slic3r::GUI::GUI_App::show_network_plugin_download_dialog ( bool is_update = false)
2152{
2153 auto load_error = Slic3r::NetworkAgent::get_load_error();
2154
2156 if (load_error.has_error) {
2158 } else if (is_update) {
2160 } else {
2162 }
2163
2164 std::string current_version = Slic3r::NetworkAgent::get_version();
2165
2166 NetworkPluginDownloadDialog dlg(mainframe, mode, current_version,
2167 load_error.message, load_error.technical_details);
2168
2169 int result = dlg.ShowModal();
2170
2171 switch (result) {
2173 {
2174 std::string selected = dlg.get_selected_version();
2175 app_config->set_network_plugin_version(selected);
2176 app_config->save();
2177
2178 DownloadProgressDialog download_dlg(_L("Downloading Network Plug-in"));
2179 download_dlg.ShowModal();
2180 }
2181 break;
2182
2184 app_config->set_remind_network_update_later(true);
2185 app_config->save();
2186 break;
2187
2189 {
2190 std::string latest = get_latest_network_version();
2191 app_config->add_skipped_network_version(latest);
2192 app_config->save();
2193 }
2194 break;
2195
2197 app_config->set_network_update_prompt_disabled(true);
2198 app_config->save();
2199 break;
2200
2202 default:
2203 break;
2204 }
2205}
@ RESULT_DONT_ASK
Definition NetworkPluginDialog.hpp:45
@ RESULT_SKIP_VERSION
Definition NetworkPluginDialog.hpp:44
@ RESULT_SKIP
Definition NetworkPluginDialog.hpp:42
@ RESULT_REMIND_LATER
Definition NetworkPluginDialog.hpp:43
@ RESULT_DOWNLOAD
Definition NetworkPluginDialog.hpp:41
Mode
Definition NetworkPluginDialog.hpp:27
@ UpdateAvailable
Definition NetworkPluginDialog.hpp:29
@ MissingPlugin
Definition NetworkPluginDialog.hpp:28
@ CorruptedPlugin
Definition NetworkPluginDialog.hpp:30
static NetworkLibraryLoadError get_load_error()
Definition NetworkAgent.cpp:88

References _L, app_config, Slic3r::GUI::NetworkPluginDownloadDialog::CorruptedPlugin, get_latest_network_version(), Slic3r::NetworkAgent::get_load_error(), Slic3r::GUI::NetworkPluginDownloadDialog::get_selected_version(), Slic3r::NetworkAgent::get_version(), mainframe, Slic3r::GUI::NetworkPluginDownloadDialog::MissingPlugin, Slic3r::GUI::NetworkPluginDownloadDialog::RESULT_DONT_ASK, Slic3r::GUI::NetworkPluginDownloadDialog::RESULT_DOWNLOAD, Slic3r::GUI::NetworkPluginDownloadDialog::RESULT_REMIND_LATER, Slic3r::GUI::NetworkPluginDownloadDialog::RESULT_SKIP, Slic3r::GUI::NetworkPluginDownloadDialog::RESULT_SKIP_VERSION, Slic3r::GUI::DPIAware< P >::ShowModal(), and Slic3r::GUI::NetworkPluginDownloadDialog::UpdateAvailable.

Referenced by on_init_network(), and post_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_outline()

bool Slic3r::GUI::GUI_App::show_outline ( ) const
inline
456{ return app_config->get_bool("show_outline"); }

References app_config.

Referenced by toggle_show_outline().

Here is the caller graph for this function:

◆ show_plate_gridlines()

bool Slic3r::GUI::GUI_App::show_plate_gridlines ( ) const
inline
448{ return app_config->get_bool("show_plate_gridlines"); }

References app_config.

Referenced by toggle_show_plate_gridlines().

Here is the caller graph for this function:

◆ ShowDownNetPluginDlg()

void Slic3r::GUI::GUI_App::ShowDownNetPluginDlg ( )
5039 {
5040 try {
5041 auto iter = std::find_if(dialogStack.begin(), dialogStack.end(), [](auto dialog) {
5042 return dynamic_cast<DownloadProgressDialog *>(dialog) != nullptr;
5043 });
5044 if (iter != dialogStack.end())
5045 return;
5046 DownloadProgressDialog dlg(_L("Downloading Bambu Network Plug-in"));
5047 dlg.ShowModal();
5048 } catch (std::exception &) {
5049 ;
5050 }
5051}

References _L, Slic3r::GUI::dialogStack, ShowDownNetPluginDlg(), and Slic3r::GUI::DPIAware< P >::ShowModal().

Referenced by ShowDownNetPluginDlg().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ShowOnlyFilament()

void Slic3r::GUI::GUI_App::ShowOnlyFilament ( )
5072 {
5073 // BBS:Show NewUser Guide
5074 try {
5075 bool res = false;
5076 GuideFrame GuideDlg(this);
5077 GuideDlg.SetStartPage(GuideFrame::GuidePage::BBL_FILAMENT_ONLY);
5078 res = GuideDlg.run();
5079 if (res) {
5081
5082 // BBS: remove SLA related message
5083 }
5084 } catch (std::exception &) {
5085 // wxMessageBox(e.what(), "", MB_OK);
5086 }
5087}

References Slic3r::GUI::GuideFrame::BBL_FILAMENT_ONLY, load_current_presets(), Slic3r::GUI::GuideFrame::run(), Slic3r::GUI::GuideFrame::SetStartPage(), and ShowOnlyFilament().

Referenced by ShowOnlyFilament().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ShowUserGuide()

void Slic3r::GUI::GUI_App::ShowUserGuide ( )
5021 {
5022 // BBS:Show NewUser Guide
5023 try {
5024 bool res = false;
5025 GuideFrame GuideDlg(this);
5026 //if (GuideDlg.IsFirstUse())
5027 res = GuideDlg.run();
5028if (res) {
5031 mainframe->refresh_plugin_tips();
5032 // BBS: remove SLA related message
5033 }
5034 } catch (std::exception &) {
5035 // wxMessageBox(e.what(), "", MB_OK);
5036 }
5037}

References load_current_presets(), mainframe, Slic3r::GUI::GuideFrame::run(), ShowUserGuide(), and update_publish_status().

Referenced by ShowUserGuide().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ShowUserLogin()

void Slic3r::GUI::GUI_App::ShowUserLogin ( bool show = true,
const std::string & provider = ORCA_CLOUD_PROVIDER )
5054{
5055 // Show user Login Dialog for specified cloud
5056 if (show) {
5057 try {
5058 delete login_dlg;
5059 auto cloud_agent = m_agent->get_cloud_agent(provider);
5060 login_dlg = new ZUserLogin(cloud_agent);
5061 login_dlg->ShowModal();
5062 } catch (std::exception &) {
5063 ;
5064 }
5065 } else {
5066 if (login_dlg)
5067 login_dlg->EndModal(wxID_OK);
5068 }
5069}

References login_dlg, m_agent, and ShowUserLogin().

Referenced by check_login(), request_login(), and ShowUserLogin().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ shutdown()

void Slic3r::GUI::GUI_App::shutdown ( )
1276{
1277 BOOST_LOG_TRIVIAL(info) << "GUI_App::shutdown enter";
1278
1281 }
1282
1283 // destroy login dialog
1284 if (login_dlg != nullptr) {
1285 BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": destroy login dialog");
1286 delete login_dlg;
1287 login_dlg = nullptr;
1288 }
1289
1290 if (m_is_recreating_gui) return;
1292 set_closing(true);
1294
1295 if (m_agent)
1296 m_agent->set_printer_agent(nullptr);
1298
1299 BOOST_LOG_TRIVIAL(info) << "GUI_App::shutdown exit";
1300}
void set_closing(bool closing)
Definition GUI_App.hpp:437
RemovableDriveManager * removable_drive_manager()
Definition GUI_App.hpp:807
void shutdown()
Definition RemovableDriveManager.cpp:426
void set_shutting_down()
Definition PluginManager.cpp:148

References Slic3r::NetworkAgentFactory::clear_printer_agent_cache(), Slic3r::PluginManager::instance(), login_dlg, m_agent, m_is_recreating_gui, m_removable_drive_manager, removable_drive_manager(), set_closing(), Slic3r::PluginManager::set_shutting_down(), Slic3r::GUI::RemovableDriveManager::shutdown(), and stop_http_server().

Here is the call graph for this function:

◆ sidebar()

Sidebar & Slic3r::GUI::GUI_App::sidebar ( )
9684{
9685 return plater_->sidebar();
9686}

References plater_, and sidebar().

Referenced by obj_layers(), obj_list(), obj_settings(), on_init_inner(), recreate_GUI(), set_live_printer_agent(), sidebar(), and update_mode().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ single_instance_checker()

wxSingleInstanceChecker * Slic3r::GUI::GUI_App::single_instance_checker ( )
inline
809{return m_single_instance_checker.get();}

References m_single_instance_checker.

◆ small_font()

const wxFont & Slic3r::GUI::GUI_App::small_font ( )
inline
530{ return m_small_font; }

References m_small_font.

◆ split_str()

std::vector< std::string > Slic3r::GUI::GUI_App::split_str ( std::string src,
std::string separator )
917{
918 std::string::size_type pos;
919 std::vector<std::string> result;
920 src += separator;
921 int size = src.size();
922
923 for (int i = 0; i < size; i++)
924 {
925 pos = src.find(separator, i);
926 if (pos < size)
927 {
928 std::string s = src.substr(i, pos - i);
929 result.push_back(s);
930 i = pos + separator.size() - 1;
931 }
932 }
933 return result;
934}

◆ start_download()

void Slic3r::GUI::GUI_App::start_download ( std::string url)
10436{
10437 if (!plater_) {
10438 BOOST_LOG_TRIVIAL(error) << "Could not start URL download: plater is nullptr.";
10439 return;
10440 }
10441 //lets always init so if the download dest folder was changed, new dest is used
10442 boost::filesystem::path dest_folder(app_config->get("download_path"));
10443 // ORCA: non-throwing probe, as in init_download_path(); ec is deliberately unread.
10444 boost::system::error_code ec;
10445 if (dest_folder.empty() || !boost::filesystem::is_directory(dest_folder, ec)) {
10446 std::string msg = _u8L("Could not start URL download. Destination folder is not set. Please choose destination folder in Configuration Wizard.");
10447 BOOST_LOG_TRIVIAL(error) << msg;
10448 show_error(nullptr, msg);
10449 return;
10450 }
10451 m_downloader->init(dest_folder);
10452 m_downloader->start_download(url);
10453
10454}

References _u8L, app_config, m_downloader, plater_, Slic3r::GUI::show_error(), and start_download().

Referenced by post_init(), and start_download().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ start_exit_watchdog()

void Slic3r::GUI::GUI_App::start_exit_watchdog ( )
1303{
1304 // Last resort for code that never returns while the app closes (plugins, vendor libraries,
1305 // network calls). The app config is saved on idle and again in MainFrame::shutdown, so ending
1306 // the process loses little; static destructors and atexit handlers are skipped too, as they may
1307 // be what is stuck.
1308 constexpr auto grace = std::chrono::seconds(30);
1309 try {
1310 // Made now: by the time the watchdog fires, static destruction may be under way. The logger
1311 // holds its own reference, which keeps boost::log's core and sinks alive.
1312 boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level> logger;
1313 std::thread([grace, logger]() mutable {
1314 std::this_thread::sleep_for(grace);
1315 try {
1316 BOOST_LOG_SEV(logger, boost::log::trivial::error)
1317 << "OrcaSlicer did not finish closing within " << grace.count() << " s; ending the process";
1318 } catch (...) {
1319 // A failing log sink must not stop the exit.
1320 }
1321 std::_Exit(EXIT_FAILURE);
1322 }).detach();
1323 } catch (const std::system_error& ex) {
1324 BOOST_LOG_TRIVIAL(warning) << "Could not start the exit watchdog: " << ex.what();
1325 }
1326}

◆ start_http_server() [1/2]

void Slic3r::GUI::GUI_App::start_http_server ( const std::string & provider = ORCA_CLOUD_PROVIDER)
8329{
8330 m_http_server.set_request_handler([provider](const std::string& url) {
8331 return HttpServer::auth_handle_request(url, provider);
8332 });
8333
8334 if (!m_http_server.is_started())
8335 m_http_server.start();
8336}
HttpServer m_http_server
Definition GUI_App.hpp:376
static std::shared_ptr< Response > auth_handle_request(const std::string &url, const std::string &provider)
Definition HttpServer.cpp:225

References Slic3r::GUI::HttpServer::auth_handle_request(), m_http_server, and start_http_server().

Referenced by start_http_server(), and start_http_server().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ start_http_server() [2/2]

void Slic3r::GUI::GUI_App::start_http_server ( int port,
const std::string & provider = ORCA_CLOUD_PROVIDER )
8339{
8340 if (port <= 0) {
8341 start_http_server(provider);
8342 return;
8343 }
8344
8345 m_http_server.set_request_handler([provider](const std::string& url) {
8346 return HttpServer::auth_handle_request(url, provider);
8347 });
8348
8349 if (m_http_server.is_started()) {
8350 if (m_http_server.get_port() == static_cast<boost::asio::ip::port_type>(port)) {
8351 return;
8352 }
8353 m_http_server.stop();
8354 }
8355
8356 m_http_server.set_port(static_cast<boost::asio::ip::port_type>(port));
8357 m_http_server.start();
8358}
void start_http_server(const std::string &provider=ORCA_CLOUD_PROVIDER)
Definition GUI_App.cpp:8328

References Slic3r::GUI::HttpServer::auth_handle_request(), m_http_server, and start_http_server().

Here is the call graph for this function:

◆ start_sync_user_preset()

void Slic3r::GUI::GUI_App::start_sync_user_preset ( bool with_progress_dlg = false)
7900{
7901 if (app_config->get_stealth_mode())
7902 return;
7903
7904 if (!m_agent || !m_agent->is_user_login()) return;
7905 if(!m_agent->get_cloud_agent())
7906 return;
7907
7908 // has already start sync
7909 if (m_user_sync_token) return;
7910
7911 // Sync only when login
7912 ProgressFn progressFn;
7913 WasCancelledFn cancelFn;
7914 std::function<void(bool)> finishFn;
7915
7916 BOOST_LOG_TRIVIAL(info) << "start_sync_service...";
7917 // BBS
7918 m_user_sync_token.reset(new int(0));
7920 if (with_progress_dlg) {
7921 // Mark a manual progress dialog as active so restart_sync_user_preset() ignores
7922 // repeat triggers while it is on screen (prevents stacking modal dialogs).
7924 auto dlg = new ProgressDialog(_L("Loading"), "", 100, this->mainframe, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);
7925 dlg->Update(0, _L("Loading user preset"));
7926 progressFn = [this, dlg](int percent) {
7927 CallAfter([=]{
7928 dlg->Update(percent, _L("Loading user preset"));
7929 });
7930 };
7931 cancelFn = [this, dlg, t = std::weak_ptr<int>(m_user_sync_token)]() {
7932 return is_closing() || dlg->WasCanceled() || t.expired();
7933 };
7934 finishFn = [this, dlg](bool) {
7935 // Clear the guard together with destroying the dialog, on the GUI thread, so the
7936 // next manual sync is allowed exactly once this dialog leaves the screen.
7937 CallAfter([=]{ dlg->Destroy(); m_sync_user_preset_dlg_active = false; });
7938 };
7939 }
7940 else {
7941 finishFn = [](bool) {}; // reload_settings() is now triggered from the background thread
7942 cancelFn = [this, t = std::weak_ptr<int>(m_user_sync_token)]() {
7943 return is_closing() || t.expired();
7944 };
7945 }
7946
7947 Bind(EVT_UPDATE_PRESET_BUNDLE,&GUI_App::update_single_bundle,this);
7948
7950 [this, progressFn, cancelFn, finishFn, t = std::weak_ptr<int>(m_user_sync_token)] {
7951 // finishFn tears down the progress dialog (and clears the re-entrancy guard), so it
7952 // must run on every exit path — otherwise an early bail-out would leak the modal
7953 // dialog and leave the guard stuck, blocking all later manual syncs.
7954 // Guard the whole thread body: an uncaught exception here (e.g. a transient
7955 // boost::filesystem error while scanning the preset folder) would otherwise
7956 // propagate out of the thread and terminate the entire application.
7957 try {
7958 if (!m_agent) { finishFn(false); return; }
7959
7960 // One-time scan for orphaned .info files left over from offline deletions; queues HTTP DELETEs.
7963
7964 // get setting list, update setting list
7965 std::string version = preset_bundle->get_vendor_profile_version(PresetBundle::ORCA_DEFAULT_BUNDLE).to_string();
7966
7967 // run check_and_fix_user_presets_syncinfo once before syncing to make sure all presets have correct sync_info
7968 // So that we can sync presets that are migrated from old version or users manually put preset files in preset folder
7969 preset_bundle->check_and_fix_user_presets_syncinfo(m_agent->get_user_id());
7970
7971 int ret = m_agent->get_setting_list2(version, [this](auto info) {
7972 auto type = info[BBL_JSON_KEY_TYPE];
7973 auto name = info[BBL_JSON_KEY_NAME];
7974 auto setting_id = info[BBL_JSON_KEY_SETTING_ID];
7975 auto update_time_str = info[ORCA_JSON_KEY_UPDATE_TIME];
7976 long long update_time = 0;
7977 if (!update_time_str.empty())
7978 update_time = std::atoll(update_time_str.c_str());
7979 if (type == "filament") {
7980 return preset_bundle->filaments.need_sync(name, setting_id, update_time);
7981 } else if (type == "print") {
7982 return preset_bundle->prints.need_sync(name, setting_id, update_time);
7983 } else if (type == "printer") {
7984 return preset_bundle->printers.need_sync(name, setting_id, update_time);
7985 } else {
7986 return true;
7987 }
7988 }, progressFn, cancelFn);
7989 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " get_setting_list2 ret = " << ret << " m_is_closing = " << m_is_closing;
7990
7991 finishFn(ret == 0);
7992
7993 // Queued after the refresh reload_settings() queues, so it runs once the pulled presets are loaded.
7994 if (ret == 0 && m_agent && !t.expired() && reload_settings())
7995 CallAfter([this, t] {
7996 // A stopped or restarted sync: the next sync, if one starts, pulls the presets again.
7997 if (t.expired() || is_closing())
7998 return;
8002 });
8003
8004 // For orca specific syncing
8005 auto orca_agent = std::dynamic_pointer_cast<OrcaCloudServiceAgent>(m_agent->get_cloud_agent());
8006 int tick_tock = -1, sync_count = 0; // tick_tock = -1 to immediately run sync the frist time this thread runs
8007 std::vector<Preset> presets_to_sync;
8008 std::vector<std::pair<std::string, std::string>> bundles_to_sync;
8009 std::unordered_set<std::string> bundles_synced;
8010
8011 std::unordered_set<std::string> known_available_updates;
8012
8013 bool update_available = false;
8014 // Sync once immediately, then every 60 seconds.
8015 while (!t.expired()) {
8016 ++tick_tock;
8017 // Sync once immediately, then every 60s, or right away when a force-push or a preset migration asked
8018 // for it. The request is consumed on every tick, so one made before a scheduled pass is served by it
8019 // instead of running a second pass straight after.
8020 const bool push_now = m_sync_user_presets_now.exchange(false, std::memory_order_acq_rel);
8021 if (tick_tock % 120 == 0 || push_now) {
8022 tick_tock = 0;
8023 if (m_agent) {
8024 if (!m_agent->is_user_login()) {
8025 continue;
8026 }
8027 //sync preset
8028 if (!preset_bundle) continue;
8029
8030 int total_count = 0;
8031 sync_count = preset_bundle->prints.get_user_presets(preset_bundle, presets_to_sync);
8032
8033 auto sync_with_lock = [this](Preset& preset) {
8034 bool force = false;
8035 {
8036 std::scoped_lock lock(conflict_ids_mutex);
8037 auto it = std::find_if(m_pending_conflict_setting_ids.begin(), m_pending_conflict_setting_ids.end(),
8038 [&preset](const std::string& id) { return id == preset.setting_id; });
8039 if (it != m_pending_conflict_setting_ids.end()) {
8040 force = true;
8042 }
8043 }
8044 sync_preset(&preset, force);
8045 };
8046
8047 if (sync_count > 0) {
8048 for (Preset& preset : presets_to_sync) {
8049 sync_with_lock(preset);
8050 boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
8051 }
8052 }
8053 total_count += sync_count;
8054
8055 sync_count = preset_bundle->filaments.get_user_presets(preset_bundle, presets_to_sync);
8056 if (sync_count > 0) {
8057 for (Preset& preset : presets_to_sync) {
8058 sync_with_lock(preset);
8059 boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
8060 }
8061 }
8062 total_count += sync_count;
8063
8064 sync_count = preset_bundle->printers.get_user_presets(preset_bundle, presets_to_sync);
8065 if (sync_count > 0) {
8066 for (Preset& preset : presets_to_sync) {
8067 sync_with_lock(preset);
8068 boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
8069 }
8070 }
8071 total_count += sync_count;
8072
8073 if (total_count == 0) {
8074 CallAfter([this] {
8075 if (!is_closing())
8077 });
8078 }
8079
8081 }
8082
8083 // sync subscribed bundles, if orca
8084 if (orca_agent)
8085 {
8086 bundles_to_sync.clear();
8087 bundles_synced.clear();
8088 std::vector<std::string> not_found;
8089 std::vector<std::string> unauthorized;
8090
8091 int result = orca_agent->get_subscribed_bundles(&bundles_to_sync, not_found, unauthorized);
8092 if (result != 0) {
8093 BOOST_LOG_TRIVIAL(warning) << "start_sync_user_preset: failed to fetch subscribed bundles, result=" << result;
8094 continue;
8095 }
8096
8097 if(!not_found.empty())
8098 {
8099 for(auto& n : not_found)
8100 {
8101 std::string text = format(_L("Bundle %s is no longer available."), n);
8102 wxGetApp().plater()->get_notification_manager()->push_notification(NotificationType::CustomNotification,NotificationManager::NotificationLevel::RegularNotificationLevel,text);
8103 }
8104 }
8105 if(!unauthorized.empty())
8106 {
8107 for(auto& i : unauthorized)
8108 {
8109 std::string text = format(_L("Bundle %s access is unauthorized."), i);
8110 wxGetApp().plater()->get_notification_manager()->push_notification(NotificationType::CustomNotification,NotificationManager::NotificationLevel::RegularNotificationLevel,text);
8111 preset_bundle->bundles.ReadLock();
8112 if(preset_bundle->bundles.m_bundles.find(i) != preset_bundle->bundles.m_bundles.end())
8113 {
8114 preset_bundle->bundles.m_bundles[i].unauthorized = true;
8115 }
8116 preset_bundle->bundles.ReadUnlock();
8117 }
8118 }
8119
8120 // Iterate over the bundles, and update/create
8121 for (const auto& bundle_entry : bundles_to_sync) {
8122 bundles_synced.insert(bundle_entry.first);
8123 // Sync each bundle individually
8124 // if(!preset_bundle->bundles.pauseReads.load()) // if pause is true we will skip updating this frame altogether
8125 // {
8126 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << "ORCA : Update thread syncing bundles";
8127 int res = sync_bundle(bundle_entry.first, bundle_entry.second);
8128
8129 const std::string known_update_key = bundle_entry.first + ":" + bundle_entry.second;
8130 if (res == 1 && known_available_updates.insert(known_update_key).second) {
8131 update_available = true;
8132 }
8133
8134 // }
8135 // Small delay between bundle syncs to avoid overwhelming the server
8136 boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
8137 }
8138
8139 if (update_available) {
8140 wxGetApp()
8141 .plater()
8142 ->get_notification_manager()
8143 ->push_notification(NotificationType::CustomNotification,
8144 NotificationManager::NotificationLevel::RegularNotificationLevel, _u8L("There is an update available. Open the preset bundle dialog to update it."));
8145
8146 update_available = false;
8147 }
8148
8149 std::vector<BundleMetadata> to_delete;
8150 preset_bundle->bundles.ReadLock();
8151 for (const auto& [id, bundle] : preset_bundle->bundles.m_bundles) {
8152 if (bundle.bundle_type != BundleType::Subscribed)
8153 continue;
8154 if (bundles_synced.find(id) != bundles_synced.end())
8155 continue;
8156 if(bundle.unauthorized && bundle.is_subscribed)
8157 continue;
8158
8159 to_delete.push_back(bundle);
8160 }
8161 preset_bundle->bundles.ReadUnlock();
8162
8163 bool has_deletion = false;
8164 for (const auto& bundle : to_delete) {
8165
8166 // Delete the presets first (force=true: bundle presets have is_from_bundle=true)
8167 for (auto printer : bundle.printer_presets)
8168 preset_bundle->printers.delete_preset(printer, true);
8169 for (auto filament : bundle.filament_presets)
8170 preset_bundle->filaments.delete_preset(filament, true);
8171 for (auto print : bundle.print_presets)
8172 preset_bundle->prints.delete_preset(print, true);
8173
8174 // Delete the bundle folder and bundle
8175 fs::path bundle_folder = fs::path(bundle.path.c_str()).parent_path();
8176 {
8177 boost::system::error_code ec;
8178 InstanceLock instance_lock(user_presets_lock_path());
8179 boost::filesystem::remove_all(bundle_folder, ec);
8180 }
8181
8182 preset_bundle->bundles.WriteLock();
8183 preset_bundle->bundles.m_bundles.erase(bundle.id);
8184 preset_bundle->bundles.WriteUnlock();
8185
8186 std::string text = format(_L("%s has been removed."), bundle.name);
8187 wxGetApp().plater()->get_notification_manager()->push_notification(NotificationType::CustomNotification,NotificationManager::NotificationLevel::RegularNotificationLevel,text);
8188 has_deletion = true;
8189 }
8190
8191 // Update UI on main thread after deletion
8192 if (has_deletion)
8193 CallAfter([this]() {
8194 if (!is_closing() && preset_bundle && mainframe) {
8195 // update_compatible() ensures proper selection state after deletion
8197 preset_bundle->update_multi_material_filament_presets();
8198 mainframe->update_side_preset_ui();
8199
8200 auto* evt = new wxCommandEvent(EVT_UPDATE_BUNDLE_COMPLETE);
8201 // evt->SetString(wxString::FromUTF8(bundle_id));
8203 wxQueueEvent(m_preset_bundle_dlg, evt);
8204 else
8205 delete evt;
8206 }
8207 });
8208 }
8209 } else {
8210 boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
8211 }
8212 }
8213 } catch (const std::exception& e) {
8214 BOOST_LOG_TRIVIAL(error) << "user preset sync thread terminated by exception: " << e.what();
8215 } catch (...) {
8216 BOOST_LOG_TRIVIAL(error) << "user preset sync thread terminated by unknown exception";
8217 }
8218 });
8219}
#define BBL_JSON_KEY_NAME
Definition Preset.hpp:58
#define ORCA_JSON_KEY_UPDATE_TIME
Definition Preset.hpp:73
#define BBL_JSON_KEY_SETTING_ID
Definition Preset.hpp:68
void scan_orphaned_info_files()
Definition GUI_App.cpp:9510
void process_delete_presets()
Definition GUI_App.cpp:9440
int sync_bundle(std::string bundle_id, std::string version)
Definition GUI_App.cpp:7658
void update_single_bundle(wxCommandEvent &evt)
Definition GUI_App.cpp:7598
void sync_preset(Preset *preset, bool force=false)
Definition GUI_App.cpp:7443
bool reload_settings()
Definition GUI_App.cpp:6999
void close_notification_of_type(const NotificationType type)
Definition NotificationManager.cpp:2231
static const char * ORCA_DEFAULT_BUNDLE
Definition PresetBundle.hpp:686
@ BBLUserPresetExceedLimit
Definition NotificationManager.hpp:178
std::function< bool()> WasCancelledFn
Definition SendJob.hpp:20
boost::thread create_thread(boost::thread::attributes &attrs, Fn &&fn)
Definition Thread.hpp:48
std::function< void(int progress)> ProgressFn
Definition bambu_networking.hpp:138
@ Subscribed
Definition PresetBundle.hpp:114

References _L, _u8L, app_config, BBL_JSON_KEY_NAME, BBL_JSON_KEY_SETTING_ID, BBL_JSON_KEY_TYPE, Slic3r::GUI::BBLUserPresetExceedLimit, check_legacy_user_filament_presets(), Slic3r::GUI::conflict_ids_mutex, Slic3r::create_thread(), Slic3r::GUI::CustomNotification, Slic3r::GUI::format(), is_closing(), m_agent, m_is_closing, m_legacy_filament_check_due, m_pending_conflict_setting_ids, m_preset_bundle_dlg, m_sync_update_thread, m_sync_user_preset_dlg_active, m_sync_user_presets_now, m_user_preset_pull_pending, m_user_sync_token, mainframe, Slic3r::Never, Slic3r::PresetBundle::ORCA_DEFAULT_BUNDLE, ORCA_JSON_KEY_UPDATE_TIME, plater(), preset_bundle, process_delete_presets(), Slic3r::GUI::NotificationManager::RegularNotificationLevel, reload_settings(), scan_orphaned_info_files(), start_sync_user_preset(), Slic3r::Subscribed, sync_bundle(), sync_preset(), update_single_bundle(), and Slic3r::user_presets_lock_path().

Referenced by on_user_login_handle(), post_init(), restart_networking(), restart_sync_user_preset(), and start_sync_user_preset().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ starts_on_prepare()

bool Slic3r::GUI::GUI_App::starts_on_prepare ( ) const
8735{
8736 return app_config->get("default_page") == "1";
8737}

References app_config, and starts_on_prepare().

Referenced by on_init_inner(), post_init(), and starts_on_prepare().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ stop_http_server()

void Slic3r::GUI::GUI_App::stop_http_server ( )
8361{
8362 m_http_server.stop();
8363}

References m_http_server, and stop_http_server().

Referenced by OnExit(), shutdown(), and stop_http_server().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ stop_sync_user_preset()

void Slic3r::GUI::GUI_App::stop_sync_user_preset ( )
8222{
8223 if (!m_user_sync_token)
8224 return;
8225
8226 m_user_sync_token.reset();
8227 if (m_sync_update_thread.joinable()) {
8228 if (is_closing())
8229 m_sync_update_thread.join();
8230 else
8231 m_sync_update_thread.detach();
8232 }
8233}

References is_closing(), m_sync_update_thread, m_user_sync_token, and stop_sync_user_preset().

Referenced by on_init_inner(), on_stealth_mode_enter(), OnExit(), and stop_sync_user_preset().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ switch_printer_agent()

void Slic3r::GUI::GUI_App::switch_printer_agent ( )
4275{
4276 if (!m_agent) {
4277 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": no agent exists";
4278 return;
4279 }
4280
4281 // why: installing an agent updates the sidebar and the main frame's print button; until the
4282 // main window exists, load_current_presets() has not run Tab::on_presets_changed(), which
4283 // installs the selected preset's agent once the window is up
4284 if (!mainframe || !plater_)
4285 return;
4286
4287 const DynamicPrintConfig& config = preset_bundle->printers.get_edited_preset().config;
4288 const std::string effective_agent_id = resolve_printer_agent_id(config.opt_string("printer_agent"));
4289
4290 // Check if agent is registered
4291 const PrinterAgentInfo* agent_info_ptr = NetworkAgentFactory::get_printer_agent_info(effective_agent_id);
4292 if (!agent_info_ptr) {
4293 // why: the selected agent's provider is gone (e.g. plugin unloaded); leaving the old
4294 // live agent up would keep talking to a machine the user can no longer select.
4295 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": agent ID '" << effective_agent_id
4296 << "' is unregistered; clearing live printer agent";
4297 set_live_printer_agent(nullptr);
4298 return;
4299 }
4300 const PrinterAgentInfo agent_info = *agent_info_ptr;
4301
4302 std::string log_dir = data_dir();
4303 std::string cloud_agent_id = agent_info.id == BBL_PRINTER_AGENT_ID ? BBL_CLOUD_PROVIDER : ORCA_CLOUD_PROVIDER;
4304 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " " << agent_info.id;
4305 std::shared_ptr<ICloudServiceAgent> cloud_agent = m_agent->get_cloud_agent(cloud_agent_id);
4306
4307 // Create new printer agent via registry
4308 std::shared_ptr<IPrinterAgent> new_printer_agent =
4309 NetworkAgentFactory::create_printer_agent_by_id(effective_agent_id, cloud_agent, log_dir);
4310
4311 if (!new_printer_agent) {
4312 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": failed to create agent '" << effective_agent_id
4313 << "'; clearing live printer agent";
4314 set_live_printer_agent(nullptr);
4315 return;
4316 }
4317
4318 // Compare the registered IDs, not only the implementation pointer. Different registry IDs
4319 // may intentionally be backed by the same implementation object (especially for plugins).
4320 const auto current_printer_agent = m_agent->get_printer_agent();
4321 if (current_printer_agent && current_printer_agent->get_agent_info().id == effective_agent_id) {
4322 // Orca: the agent type is unchanged (e.g. switching between two Moonraker/Klipper
4323 // printer presets), so the selected machine and the agent's cached device_info still
4324 // point at the previously active printer preset. Re-select the machine when the new
4325 // preset targets a different host, otherwise filament sync keeps hitting the old
4326 // printer. (#12506)
4327 if (effective_agent_id != BBL_PRINTER_AGENT_ID && m_device_manager && preset_bundle) {
4328 const std::string print_host = config.opt_string("print_host");
4329 if (!print_host.empty()) {
4330 const std::string dev_id = MachineObject::dev_id_from_address(print_host, config.opt_string("printhost_port"));
4331 MachineObject* sel = m_device_manager->get_selected_machine();
4332 const bool access_code_changed = effective_agent_id == MOONRAKER_PRINTER_AGENT_ID && sel &&
4333 sel->get_access_code() != config.opt_string("printhost_apikey");
4334 if (!sel || sel->get_dev_id() != dev_id || access_code_changed)
4335 select_machine(effective_agent_id);
4336 }
4337 }
4338 return;
4339 }
4340
4341 // Swap the agent; set_live_printer_agent resets the device selection so the new
4342 // agent starts clean (#124).
4343 set_live_printer_agent(new_printer_agent);
4344
4345 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": printer agent switched to " << effective_agent_id;
4346
4347 // Start discovery so Python agents can populate the device list via SSDP callback
4348 m_agent->start_discovery(true, false);
4349
4350 // Auto-switch MachineObject (new agent has empty device_info, so always re-select)
4351 select_machine(effective_agent_id);
4352}
void select_machine(const std::string &agent_id)
Definition GUI_App.cpp:4369
void set_live_printer_agent(std::shared_ptr< IPrinterAgent > agent)
Definition GUI_App.cpp:4239
static const PrinterAgentInfo * get_printer_agent_info(const std::string &id)
Definition NetworkAgentFactory.cpp:98
static std::shared_ptr< IPrinterAgent > create_printer_agent_by_id(const std::string &id, std::shared_ptr< ICloudServiceAgent > cloud_agent, const std::string &log_dir)
Definition NetworkAgentFactory.cpp:134

References Slic3r::BBL_CLOUD_PROVIDER(), Slic3r::BBL_PRINTER_AGENT_ID, Slic3r::NetworkAgentFactory::create_printer_agent_by_id(), Slic3r::data_dir(), Slic3r::MachineObject::dev_id_from_address(), Slic3r::MachineObject::get_access_code(), Slic3r::MachineObject::get_dev_id(), Slic3r::NetworkAgentFactory::get_printer_agent_info(), Slic3r::PrinterAgentInfo::id, m_agent, m_device_manager, mainframe, Slic3r::MOONRAKER_PRINTER_AGENT_ID, Slic3r::DynamicConfig::opt_string(), Slic3r::ORCA_CLOUD_PROVIDER(), plater_, preset_bundle, resolve_printer_agent_id(), select_machine(), set_live_printer_agent(), and switch_printer_agent().

Referenced by init_plugin_gui_wiring(), restart_networking(), switch_printer_agent(), and switch_printer_agent_if_pending().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ switch_printer_agent_if_pending()

void Slic3r::GUI::GUI_App::switch_printer_agent_if_pending ( )
4355{
4356 if (!m_agent || !preset_bundle)
4357 return;
4358
4359 const std::string wanted_agent_id = resolve_printer_agent_id(preset_bundle->printers.get_edited_preset().config.opt_string("printer_agent"));
4360 const auto live_agent = m_agent->get_printer_agent();
4361 if (live_agent && live_agent->get_agent_info().id == wanted_agent_id)
4362 return;
4363 if (!NetworkAgentFactory::get_printer_agent_info(wanted_agent_id))
4364 return;
4365
4367}

References Slic3r::NetworkAgentFactory::get_printer_agent_info(), m_agent, preset_bundle, resolve_printer_agent_id(), switch_printer_agent(), and switch_printer_agent_if_pending().

Referenced by init_plugin_gui_wiring(), and switch_printer_agent_if_pending().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sync_bundle()

int Slic3r::GUI::GUI_App::sync_bundle ( std::string bundle_id,
std::string version )
7659{
7660 // if(preset_bundle->bundles.pauseReads.load())
7661 // {
7662 // BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << "ORCA : Update thread sync_bundle function yielded to main thread. 1";
7663 // return; // if the main thread acquires the lock at the start of our operations, we will yield
7664 // }
7665 if (!m_agent || !m_agent->is_user_login()) return 0;
7666 auto orca_agent = std::dynamic_pointer_cast<OrcaCloudServiceAgent>(m_agent->get_cloud_agent());
7667 if (!orca_agent) return 0;
7668
7669 BOOST_LOG_TRIVIAL(info) << "sync_bundle: checking bundle " << bundle_id << " for updates";
7670
7671 bool is_new = false;
7672 bool is_update = false;
7673
7674 preset_bundle->bundles.ReadLock(); // acquire a read lock to check for updates
7675
7676 // if bundle already downloaded, check for updates
7677 auto bundle_it = preset_bundle->bundles.m_bundles.find(bundle_id);
7678 if (bundle_it != preset_bundle->bundles.m_bundles.end()) {
7679
7680 // Check if remote version is newer using Semver comparison
7681 auto local_version = Semver::parse(bundle_it->second.version);
7682 auto remote_version = Semver::parse(version);
7683
7684 BOOST_LOG_TRIVIAL(info) << "sync_bundle: comparing local version: " << local_version << " to remote version: " << remote_version;
7685
7686 if (!local_version || !remote_version) {
7687 BOOST_LOG_TRIVIAL(warning) << "sync_bundle: failed to parse versions for bundle " << bundle_id
7688 << " (local: " << local_version << ", remote: " << remote_version << ")";
7689 preset_bundle->bundles.ReadUnlock(); // unlock read when fail
7690 return -1;
7691 }
7692 if (remote_version <= local_version) {
7693 BOOST_LOG_TRIVIAL(info) << "sync_bundle: bundle " << bundle_id << " is up-to-date (version " << local_version << ")";
7694 preset_bundle->bundles.ReadUnlock(); // unlock read when fail
7695 return -1;
7696 }
7697 BOOST_LOG_TRIVIAL(info) << "sync_bundle: updating bundle " << bundle_id
7698 << " from version " << local_version
7699 << " to version " << remote_version;
7700 is_update = true;
7701
7702 }
7703 else {
7704 BOOST_LOG_TRIVIAL(info) << "sync_bundle: pulling newly subscribed bundle " << bundle_id << " at version " << version;
7705 is_new = true;
7706 }
7707
7708 preset_bundle->bundles.ReadUnlock(); // yield the read lock after checking for updates
7709
7710 // if it is an update, we will lock and write
7711 std::string ver;
7712 if (is_update) {
7713 preset_bundle->bundles.WriteLock();
7714 preset_bundle->bundles.m_bundles[bundle_id].update_available = true;
7715 preset_bundle->bundles.m_bundles[bundle_id].is_subscribed = true;
7716 ver = preset_bundle->bundles.m_bundles[bundle_id].version;
7717 preset_bundle->bundles.WriteUnlock();
7718 }
7719
7720 const bool auto_update = app_config->get_bool("preset_bundle_auto_update");
7721
7722 if (is_update && !auto_update) {
7723 return 1;
7724 }
7725
7726 if (auto_update || is_new) {
7727 // Fetch the latest bundle data from cloud
7728 std::map<std::string, std::map<std::string, std::string>> bundle_presets;
7729 BundleMetadata remote_metadata;
7730 int result = orca_agent->get_shared_bundle(bundle_id, &bundle_presets, &remote_metadata);
7731
7732 if (result != 0) {
7733 BOOST_LOG_TRIVIAL(warning) << "sync_bundle: failed to fetch bundle " << bundle_id << ", result=" << result;
7734 return -1;
7735 }
7736
7737 // Import the updated bundle on the main thread
7738 CallAfter(
7739 [this, bundle_id, bundle_presets, remote_metadata, is_new, is_update, ver]() {
7740 if (!is_closing() && preset_bundle && app_config) {
7741 // Check the presets for any system vendors that need to be installed
7742 for (auto data : bundle_presets) {
7743 if (!check_preset_parent_available(data)) {
7745 }
7746 }
7748
7749 // if(!preset_bundle->bundles.pauseReads.load()) // check again if we can actually update so as to not block the main thread
7750 // {
7751 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << "ORCA : CallAfter from sync_bundle function actually updating subscribed presets";
7752
7753 preset_bundle->bundles.WriteLock();
7754
7755 preset_bundle->update_subscribed_presets(*app_config, bundle_presets, remote_metadata, ForwardCompatibilitySubstitutionRule::Enable);
7756
7757 preset_bundle->bundles.WriteUnlock();
7758
7759 if(is_new)
7760 {
7761 std::string text = format(_L("%s has been downloaded."), remote_metadata.name);
7762 wxGetApp().plater()->get_notification_manager()->push_notification(NotificationType::CustomNotification,NotificationManager::NotificationLevel::RegularNotificationLevel,text);
7763 }
7764 else if(is_update)
7765 {
7766 std::string text = format(_L("%s updated from %s to %s"), remote_metadata.name, ver, remote_metadata.version);
7767 wxGetApp().plater()->get_notification_manager()->push_notification(NotificationType::CustomNotification,NotificationManager::NotificationLevel::RegularNotificationLevel,text);
7768 }
7769
7770 auto* evt = new wxCommandEvent(EVT_UPDATE_BUNDLE_COMPLETE);
7771 // evt->SetString(wxString::FromUTF8(bundle_id));
7773 wxQueueEvent(m_preset_bundle_dlg, evt);
7774 else
7775 delete evt;
7776
7777 if (mainframe)
7778 mainframe->update_side_preset_ui();
7779 BOOST_LOG_TRIVIAL(info) << "sync_bundle: successfully updated bundle " << bundle_id;
7780 // }
7781 }
7782 });
7783 }
7784
7785 return 0;
7786}

References _L, add_pending_vendor_preset(), app_config, check_preset_parent_available(), Slic3r::GUI::CustomNotification, Slic3r::Enable, Slic3r::GUI::format(), is_closing(), load_pending_vendors(), m_agent, m_preset_bundle_dlg, mainframe, Slic3r::BundleMetadata::name, Slic3r::Semver::parse(), preset_bundle, Slic3r::GUI::NotificationManager::RegularNotificationLevel, sync_bundle(), and Slic3r::BundleMetadata::version.

Referenced by start_sync_user_preset(), and sync_bundle().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sync_preset()

void Slic3r::GUI::GUI_App::sync_preset ( Preset * preset,
bool force = false )
7444{
7445 int result = -1;
7446 unsigned int http_code = 200;
7447 std::string updated_info;
7448 long long update_time = 0;
7449 // only sync user's preset
7450 if (!m_agent) return;
7451 if (!preset->is_user()) return;
7452
7453 auto setting_id = preset->setting_id;
7454 std::map<std::string, std::string> values_map;
7455
7456 // Check and catch if the file is new and missing .info
7457 bool needs_init = setting_id.empty() && preset->sync_info.empty();
7458
7459 // Actually process sync info
7460 if (needs_init || preset->sync_info.compare("create") == 0) {
7461 if (m_create_preset_blocked[preset->type])
7462 return;
7463 int ret = preset_bundle->get_differed_values_to_update(*preset, values_map);
7464 if (!ret) {
7465 std::string new_setting_id = m_agent->request_setting_id(preset->name, &values_map, &http_code);
7466 if (!new_setting_id.empty()) {
7467 setting_id = new_setting_id;
7468 result = 0;
7469 auto update_time_str = values_map[ORCA_JSON_KEY_UPDATE_TIME];
7470 if (!update_time_str.empty())
7471 update_time = std::atoll(update_time_str.c_str());
7472 }
7473 else {
7474 BOOST_LOG_TRIVIAL(trace) << "[sync_preset]init: request_setting_id failed, http code "<<http_code;
7475 // do not post new preset this time if http code >= 400
7476 if (http_code >= 400) {
7477 result = 0;
7478 updated_info = "hold";
7479 } else
7480 result = -1;
7481 }
7482 }
7483 else {
7484 BOOST_LOG_TRIVIAL(trace) << "[sync_preset]init: can not generate differed key-values";
7485 result = 0;
7486 updated_info = "hold";
7487 }
7488 }
7489 else if (preset->sync_info.compare("create") == 0) {
7490 if (m_create_preset_blocked[preset->type])
7491 return;
7492 int ret = preset_bundle->get_differed_values_to_update(*preset, values_map);
7493 if (!ret) {
7494 std::string new_setting_id = m_agent->request_setting_id(preset->name, &values_map, &http_code);
7495 if (!new_setting_id.empty()) {
7496 setting_id = new_setting_id;
7497 result = 0;
7498 auto update_time_str = values_map[ORCA_JSON_KEY_UPDATE_TIME];
7499 if (!update_time_str.empty())
7500 update_time = std::atoll(update_time_str.c_str());
7501 } else {
7502 BOOST_LOG_TRIVIAL(trace) << "[sync_preset]create: request_setting_id failed, http code "<<http_code;
7503 // do not post new preset this time if http code >= 400
7504 if (http_code >= 400) {
7505 result = 0;
7506 updated_info = "hold";
7507 }
7508 }
7509 } else {
7510 BOOST_LOG_TRIVIAL(trace) << "[sync_preset]create: can not generate differed preset";
7511 }
7512 } else if (preset->sync_info.compare("update") == 0) {
7513 if (!setting_id.empty()) {
7514 int ret = preset_bundle->get_differed_values_to_update(*preset, values_map);
7515 if (!ret) {
7516 if (auto iter = values_map.find(BBL_JSON_KEY_BASE_ID); iter != values_map.end() && iter->second == setting_id) {
7517 //clear the setting_id in this case ???
7518 setting_id.clear();
7519 result = 0;
7520 }
7521 else {
7522 result = m_agent->put_setting(setting_id, preset->name, &values_map, &http_code, ORCA_CLOUD_PROVIDER, force);
7523 if (http_code >= 400) {
7524 result = 0;
7525 updated_info = "hold";
7526 BOOST_LOG_TRIVIAL(error) << "[sync_preset] put setting_id = " << setting_id << " failed, http_code = " << http_code;
7527 } else {
7528 auto update_time_str = values_map[ORCA_JSON_KEY_UPDATE_TIME];
7529 if (!update_time_str.empty())
7530 update_time = std::atoll(update_time_str.c_str());
7531 }
7532 }
7533
7534 }
7535 else {
7536 BOOST_LOG_TRIVIAL(trace) << "[sync_preset]update: can not generate differed key-values, we need to skip this preset "<< preset->name;
7537 result = 0;
7538 }
7539 }
7540 else {
7541 //clear the sync_info
7542 result = 0;
7543 }
7544 }
7545
7546 if (http_code >= 400 && values_map["code"] == "14") { // Limit
7547 m_create_preset_blocked[preset->type] = true;
7548 CallAfter([this] {
7550 static bool dialog_notified = false;
7551 if (dialog_notified)
7552 return;
7553 dialog_notified = true;
7554 if (mainframe == nullptr)
7555 return;
7556 auto msg = _L("The number of user presets cached in the cloud has exceeded the upper limit, newly created user presets can only be used locally.");
7557 MessageDialog(mainframe, msg, _L("Sync user presets"), wxICON_WARNING | wxOK).ShowModal();
7558 });
7559 return; // this error not need hold, and should not hold
7560 }
7561
7562 // Handle HTTP 413 - Payload Too Large
7563 if (http_code == 413) {
7564 // Set sync_info to "will_not_sync" so this preset won't be synced again
7565 updated_info = "will_not_sync";
7566 result = 0; // Set to 0 so the sync_info gets saved below
7567
7568 // Show user notification
7569 CallAfter([this, name = preset->name] {
7570 static bool size_limit_dialog_notified = false;
7571 if (size_limit_dialog_notified)
7572 return;
7573 size_limit_dialog_notified = true;
7574 if (mainframe == nullptr)
7575 return;
7576 auto msg = format_wxstr(_L("The preset \"%s\" is too large to sync to the cloud (exceeds 1MB). Please reduce the preset size by removing custom configurations or use it locally only."), name);
7577 MessageDialog(mainframe, msg, _L("Sync user presets"), wxICON_WARNING | wxOK).ShowModal();
7578 });
7579 // NOTE: Don't return here - let execution continue to save the sync_info
7580 }
7581
7582 // update sync_info preset info in file
7583 if (result == 0) {
7584 //PresetBundle* preset_bundle = wxGetApp().preset_bundle;
7585 if (!this->preset_bundle) return;
7586
7587 BOOST_LOG_TRIVIAL(trace) << "sync_preset: sync operation: " << preset->sync_info << " success! preset = " << preset->name;
7588 if (preset->type == Preset::Type::TYPE_FILAMENT) {
7589 preset_bundle->filaments.set_sync_info_and_save(preset->name, setting_id, updated_info, update_time, m_agent->get_user_id());
7590 } else if (preset->type == Preset::Type::TYPE_PRINT) {
7591 preset_bundle->prints.set_sync_info_and_save(preset->name, setting_id, updated_info, update_time, m_agent->get_user_id());
7592 } else if (preset->type == Preset::Type::TYPE_PRINTER) {
7593 preset_bundle->printers.set_sync_info_and_save(preset->name, setting_id, updated_info, update_time, m_agent->get_user_id());
7594 }
7595 }
7596}
#define BBL_JSON_KEY_BASE_ID
Definition Preset.hpp:69

References _L, BBL_JSON_KEY_BASE_ID, Slic3r::GUI::BBLUserPresetExceedLimit, Slic3r::Preset::is_user(), m_agent, m_create_preset_blocked, mainframe, Slic3r::Preset::name, Slic3r::ORCA_CLOUD_PROVIDER(), ORCA_JSON_KEY_UPDATE_TIME, plater(), preset_bundle, Slic3r::Preset::setting_id, Slic3r::GUI::DPIAware< P >::ShowModal(), Slic3r::Preset::sync_info, sync_preset(), Slic3r::trace(), Slic3r::Preset::type, Slic3r::Preset::TYPE_FILAMENT, Slic3r::Preset::TYPE_PRINT, and Slic3r::Preset::TYPE_PRINTER.

Referenced by start_sync_user_preset(), and sync_preset().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ tab_panel()

Notebook * Slic3r::GUI::GUI_App::tab_panel ( ) const
9872{
9873 if (mainframe)
9874 return mainframe->m_tabpanel;
9875 return nullptr;
9876}

References mainframe, and tab_panel().

Referenced by tab_panel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ tabs_as_menu()

bool Slic3r::GUI::GUI_App::tabs_as_menu ( ) const
4857{
4858 return false;
4859}

References tabs_as_menu().

Referenced by tabs_as_menu(), and update_mode().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ toggle_canvas_zoom_button()

void Slic3r::GUI::GUI_App::toggle_canvas_zoom_button ( ) const
inline
454{ app_config->set_bool("show_canvas_zoom_button", !show_canvas_zoom_button()); }
bool show_canvas_zoom_button() const
Definition GUI_App.hpp:453

References app_config, and show_canvas_zoom_button().

Here is the call graph for this function:

◆ toggle_focus_mode()

void Slic3r::GUI::GUI_App::toggle_focus_mode ( ) const
inline
451{ app_config->set_bool("focus_mode", !focus_mode()); }
bool focus_mode() const
Definition GUI_App.hpp:450

References app_config, and focus_mode().

Here is the call graph for this function:

◆ toggle_show_3d_navigator()

void Slic3r::GUI::GUI_App::toggle_show_3d_navigator ( ) const
inline
446{ app_config->set_bool("show_3d_navigator", !show_3d_navigator()); }
bool show_3d_navigator() const
Definition GUI_App.hpp:445

References app_config, and show_3d_navigator().

Here is the call graph for this function:

◆ toggle_show_center_of_mass()

void Slic3r::GUI::GUI_App::toggle_show_center_of_mass ( ) const
inline
460{ app_config->set_bool("show_center_of_mass", !show_center_of_mass()); }
bool show_center_of_mass() const
Definition GUI_App.hpp:459

References app_config, and show_center_of_mass().

Here is the call graph for this function:

◆ toggle_show_gcode_window()

void Slic3r::GUI::GUI_App::toggle_show_gcode_window ( )
911{
913 app_config->set_bool("show_gcode_window", m_show_gcode_window);
914}

References app_config, and m_show_gcode_window.

◆ toggle_show_outline()

void Slic3r::GUI::GUI_App::toggle_show_outline ( ) const
inline
457{ app_config->set_bool("show_outline", !show_outline()); }
bool show_outline() const
Definition GUI_App.hpp:456

References app_config, and show_outline().

Here is the call graph for this function:

◆ toggle_show_plate_gridlines()

void Slic3r::GUI::GUI_App::toggle_show_plate_gridlines ( ) const
inline
449{ app_config->set_bool("show_plate_gridlines", !show_plate_gridlines()); }
bool show_plate_gridlines() const
Definition GUI_App.hpp:448

References app_config, and show_plate_gridlines().

Here is the call graph for this function:

◆ toolbar_icon_scale()

float Slic3r::GUI::GUI_App::toolbar_icon_scale ( const bool is_limited = false) const
4867{
4868#ifdef __APPLE__
4869 const float icon_sc = 1.0f; // for Retina display will be used its own scale
4870#else
4871 const float icon_sc = m_em_unit * 0.1f;
4872#endif // __APPLE__
4873
4874 //return icon_sc;
4875
4876 const std::string& auto_val = app_config->get("toolkit_size");
4877
4878 if (auto_val.empty())
4879 return icon_sc;
4880
4881 int int_val = 100;
4882 // correct value in respect to toolkit_size
4883 int_val = std::min(atoi(auto_val.c_str()), int_val);
4884
4885 if (is_limited && int_val < 50)
4886 int_val = 50;
4887
4888 return 0.01f * int_val * icon_sc;
4889}

References app_config, m_em_unit, and toolbar_icon_scale().

Referenced by toolbar_icon_scale().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ transition_tridid()

wxString Slic3r::GUI::GUI_App::transition_tridid ( int trid_id) const
5260{
5261 if (trid_id == VIRTUAL_TRAY_MAIN_ID || trid_id == VIRTUAL_TRAY_DEPUTY_ID)
5262 {
5263 assert(0);
5264 return _L("Ext");
5265 }
5266
5267 wxString maping_dict[] = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };
5268
5269 if (trid_id >= 128 * 4) {
5270 trid_id -= 128 * 4;
5271 int id_index = trid_id / 4;
5272 return wxString::Format("%s", maping_dict[id_index]);
5273 }
5274 else if (trid_id >= 0x80 && trid_id <= 0x87) { // n3s
5275 const char base = 'A' + (trid_id - 128);
5276 wxString prefix("HT-");
5277 prefix.append(base);
5278 return prefix;
5279 }
5280 else {
5281 int id_index = std::clamp((int)ceil(trid_id / 4), 0, 25);
5282 int id_suffix = trid_id % 4 + 1;
5283 return wxString::Format("%s%d", maping_dict[id_index], id_suffix);
5284 }
5285}
#define VIRTUAL_TRAY_DEPUTY_ID
Definition DevDefs.h:90
#define VIRTUAL_TRAY_MAIN_ID
Definition DevDefs.h:89

References _L, transition_tridid(), VIRTUAL_TRAY_DEPUTY_ID, and VIRTUAL_TRAY_MAIN_ID.

Referenced by transition_tridid().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ troubleshoot()

void Slic3r::GUI::GUI_App::troubleshoot ( )
5015{
5016 TroubleshootDialog dlg;
5017 if (dlg.ShowModal() == wxID_REMOVE)
5018 wxGetApp().mainframe->Close(false);
5019}

References Slic3r::GUI::DPIAware< P >::ShowModal(), and troubleshoot().

Referenced by troubleshoot().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unsubscribe_bundle()

bool Slic3r::GUI::GUI_App::unsubscribe_bundle ( const std::string & id)
7894{
7895 auto orca_agent = std::dynamic_pointer_cast<OrcaCloudServiceAgent>(m_agent->get_cloud_agent());
7896 return orca_agent->unsubscribe_bundle(id);
7897}

References m_agent, and unsubscribe_bundle().

Referenced by unsubscribe_bundle().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Update_dark_mode_flag()

void Slic3r::GUI::GUI_App::Update_dark_mode_flag ( )
4687{
4689 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": switch the current dark mode status to %1% ")%m_is_dark_mode;
4690}
bool m_is_dark_mode
Definition GUI_App.hpp:362

References dark_mode(), m_is_dark_mode, and Update_dark_mode_flag().

Referenced by on_init_inner(), and Update_dark_mode_flag().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_fonts()

void Slic3r::GUI::GUI_App::update_fonts ( const MainFrame * main_frame = nullptr)
4767{
4768 /* Only normal and bold fonts are used for an application rescale,
4769 * because of under MSW small and normal fonts are the same.
4770 * To avoid same rescaling twice, just fill this values
4771 * from rescaled MainFrame
4772 */
4773 if (main_frame == nullptr)
4774 main_frame = this->mainframe;
4775 m_normal_font = Label::Body_14; // BBS: larger font size
4777 m_bold_font = m_normal_font.Bold();
4778 m_link_font = m_bold_font.Underlined();
4779 m_em_unit = main_frame->em_unit();
4780 m_code_font.SetPointSize(m_small_font.GetPointSize());
4781}
static wxFont Body_14
Definition Label.hpp:53

References Label::Body_14, Slic3r::GUI::DPIAware< P >::em_unit(), m_bold_font, m_code_font, m_em_unit, m_link_font, m_normal_font, m_small_font, mainframe, and update_fonts().

Referenced by update_fonts().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_internal_development()

void Slic3r::GUI::GUI_App::update_internal_development ( )
8825 {
8826 if (WebViewPanel* home = WebViewPanel::if_built())
8827 home->update_mode();
8828 if (PrinterWebView* view = PrinterWebView::if_built())
8829 view->update_mode();
8830}

References Slic3r::GUI::LazyInstance< PrinterWebView >::if_built(), Slic3r::GUI::LazyInstance< WebViewPanel >::if_built(), and update_internal_development().

Referenced by update_internal_development().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_label_colours()

void Slic3r::GUI::GUI_App::update_label_colours ( )
4543{
4544 for (Tab* tab : tabs_list)
4545 tab->update_label_colours();
4546}

References tabs_list, and update_label_colours().

Referenced by update_label_colours(), and update_ui_from_settings().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_label_colours_from_appconfig()

void Slic3r::GUI::GUI_App::update_label_colours_from_appconfig ( )
4513{
4514 if (app_config->has("label_clr_sys")) {
4515 auto str = app_config->get("label_clr_sys");
4516 if (str != "")
4517 m_color_label_sys = wxColour(str);
4518 }
4519
4520 if (app_config->has("label_clr_modified")) {
4521 auto str = app_config->get("label_clr_modified");
4522 if (str != "")
4523 m_color_label_modified = wxColour(str);
4524 }
4525}

References app_config, m_color_label_modified, m_color_label_sys, and update_label_colours_from_appconfig().

Referenced by update_label_colours_from_appconfig().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_mode()

void Slic3r::GUI::GUI_App::update_mode ( )
8797{
8798 sidebar().update_mode();
8799
8800 //BBS: GUI refactor
8801 if (mainframe->m_param_panel)
8802 mainframe->m_param_panel->update_mode();
8803 if (mainframe->m_param_dialog)
8804 mainframe->m_param_dialog->panel()->update_mode();
8805 if (PrinterWebView* view = PrinterWebView::if_built())
8806 view->update_mode();
8807 if (WebViewPanel* home = WebViewPanel::if_built())
8808 home->update_mode();
8809
8810#ifdef _MSW_DARK_MODE
8811 if (!wxGetApp().tabs_as_menu())
8812 dynamic_cast<Notebook*>(mainframe->m_tabpanel)->UpdateMode();
8813#endif
8814
8815 for (auto tab : tabs_list)
8816 tab->update_mode();
8817 for (auto tab : model_tabs_list)
8818 tab->update_mode();
8819
8820 //BBS plater()->update_menus();
8821
8823}
void update_gizmos_on_off_state()
Definition GLCanvas3D.cpp:6088
bool tabs_as_menu() const
Definition GUI_App.cpp:4856
GLCanvas3D * canvas3D()
Definition Plater.cpp:22070
void update_mode()
Definition Plater.cpp:6833

References Slic3r::GUI::LazyInstance< PrinterWebView >::if_built(), Slic3r::GUI::LazyInstance< WebViewPanel >::if_built(), mainframe, model_tabs_list, plater(), sidebar(), tabs_as_menu(), tabs_list, and update_mode().

Referenced by Slic3r::GUI::anonymous_namespace{NativeCommands.cpp}::build_command_catalog(), enable_developer_mode(), on_init_inner(), recreate_GUI(), Slic3r::GUI::ConfigWizard::run(), Slic3r::GUI::GuideFrame::run(), save_mode(), and update_mode().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_publish_status()

void Slic3r::GUI::GUI_App::update_publish_status ( )
4528{
4529 // mainframe->show_publish_button(has_model_mall());
4530 // if (app_config->get("staff_pick_switch") == "true") {
4531 // mainframe->m_webview->SendDesignStaffpick(has_model_mall());
4532 // }
4533}

References update_publish_status().

Referenced by on_init_inner(), recreate_GUI(), run_wizard(), ShowUserGuide(), and update_publish_status().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_saved_preset_from_current_preset()

void Slic3r::GUI::GUI_App::update_saved_preset_from_current_preset ( )
9166{
9167 PrinterTechnology printer_technology = preset_bundle->printers.get_edited_preset().printer_technology();
9168 for (Tab* tab : tabs_list) {
9169 if (tab->supports_printer_technology(printer_technology))
9170 tab->update_saved_preset_from_current_preset();
9171 }
9172}

References preset_bundle, Slic3r::GUI::printer_technology(), tabs_list, and update_saved_preset_from_current_preset().

Referenced by update_saved_preset_from_current_preset().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_single_bundle()

void Slic3r::GUI::GUI_App::update_single_bundle ( wxCommandEvent & evt)
7599{
7600 if (!m_agent || !m_agent->is_user_login()) return;
7601 auto orca_agent = std::dynamic_pointer_cast<OrcaCloudServiceAgent>(m_agent->get_cloud_agent());
7602 if (!orca_agent) return;
7603
7604 const std::string bundle_id = evt.GetString().ToStdString();
7605
7606 // Fetch the latest bundle data from cloud
7607 std::map<std::string, std::map<std::string, std::string>> bundle_presets;
7608 BundleMetadata remote_metadata;
7609 int result = orca_agent->get_shared_bundle(bundle_id, &bundle_presets, &remote_metadata);
7610
7611 if (result != 0) {
7612 BOOST_LOG_TRIVIAL(warning) << "sync_bundle: failed to fetch bundle " << bundle_id << ", result=" << result;
7613 return;
7614 }
7615
7616 // Import the updated bundle on the main thread
7617 CallAfter([this, bundle_id, bundle_presets, remote_metadata]() {
7618 if (!is_closing() && preset_bundle && app_config) {
7619 // Check the presets for any system vendors that need to be installed
7620 for (auto data : bundle_presets) {
7621 if (!check_preset_parent_available(data)) {
7623 }
7624 }
7626
7627 preset_bundle->bundles.ReadLock();
7628 std::string initial_version = preset_bundle->bundles.m_bundles[bundle_id].version;
7629 preset_bundle->bundles.ReadUnlock();
7630
7631 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << "ORCA : CallAfter from update_single_bundle function actually updating subscribed presets";
7632
7633 preset_bundle->bundles.WriteLock();
7634
7635 preset_bundle->update_subscribed_presets(*app_config, bundle_presets, remote_metadata, ForwardCompatibilitySubstitutionRule::Enable);
7636
7637 preset_bundle->bundles.WriteUnlock();
7638
7639 std::string text = format(_L("%s updated from %s to %s"), remote_metadata.name, initial_version, remote_metadata.version);
7640 wxGetApp().plater()->get_notification_manager()->push_notification(NotificationType::CustomNotification,NotificationManager::NotificationLevel::RegularNotificationLevel,text);
7641
7642 auto* evt = new wxCommandEvent(EVT_UPDATE_BUNDLE_COMPLETE);
7643 // evt->SetString(wxString::FromUTF8(bundle_id));
7645 wxQueueEvent(m_preset_bundle_dlg, evt);
7646 else
7647 delete evt;
7648 // wxQueueEvent(&wxGetApp(), evt); // GUI_App -> dialog
7649
7650 if (mainframe)
7651 mainframe->update_side_preset_ui();
7652 BOOST_LOG_TRIVIAL(info) << "sync_bundle: successfully updated bundle " << bundle_id;
7653
7654 }
7655 });
7656}

References _L, add_pending_vendor_preset(), app_config, check_preset_parent_available(), Slic3r::GUI::CustomNotification, Slic3r::Enable, Slic3r::GUI::format(), is_closing(), load_pending_vendors(), m_agent, m_preset_bundle_dlg, mainframe, Slic3r::BundleMetadata::name, preset_bundle, Slic3r::GUI::NotificationManager::RegularNotificationLevel, update_single_bundle(), and Slic3r::BundleMetadata::version.

Referenced by start_sync_user_preset(), and update_single_bundle().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_ui_from_settings()

void Slic3r::GUI::GUI_App::update_ui_from_settings ( )
5165{
5167 // Upadte UI colors before Update UI from settings
5169 m_force_colors_update = false;
5170 //UpdateDlgDarkUI(&mainframe->m_settings_dialog);
5171 //mainframe->m_settings_dialog.Refresh();
5172 //mainframe->m_settings_dialog.Update();
5173
5174 if (mainframe) {
5175#ifdef __WINDOWS__
5176 mainframe->force_color_changed();
5177 update_scrolls(mainframe);
5178 update_scrolls(&mainframe->m_settings_dialog);
5179#endif //_MSW_DARK_MODE
5181 }
5182 }
5183
5184 if (mainframe) {mainframe->update_ui_from_settings();}
5185}
void update_label_colours()
Definition GUI_App.cpp:4542
static void update_dark_children_ui(wxWindow *window, bool just_buttons_update=false)
Definition GUI_App.cpp:4662

References m_force_colors_update, mainframe, Slic3r::GUI::update_dark_children_ui(), update_label_colours(), and update_ui_from_settings().

Referenced by update_ui_from_settings().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateAllStaticTextDarkUI()

void Slic3r::GUI::GUI_App::UpdateAllStaticTextDarkUI ( wxWindow * parent)
4736{
4737#ifdef __WINDOWS__
4738 wxGetApp().UpdateDarkUI(parent);
4739
4740 auto children = parent->GetChildren();
4741 for (auto child : children) {
4742 if (dynamic_cast<wxStaticText*>(child))
4743 child->SetForegroundColour(m_color_label_default);
4744 }
4745#endif
4746}
class WXDLLIMPEXP_FWD_CORE wxStaticText
Definition ProgressDialog.hpp:30

References m_color_label_default, and UpdateAllStaticTextDarkUI().

Referenced by UpdateAllStaticTextDarkUI().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateDarkUI()

void Slic3r::GUI::GUI_App::UpdateDarkUI ( wxWindow * window,
bool highlited = false,
bool just_font = false )
4566{
4567 if (wxButton *btn = dynamic_cast<wxButton*>(window)) {
4568 if (btn->GetWindowStyleFlag() & wxBU_AUTODRAW)
4569 return;
4570 else {
4571#ifdef _WIN32
4572 if (btn->GetId() == wxID_OK || btn->GetId() == wxID_CANCEL) {
4573 bool is_focused_button = false;
4574 bool is_default_button = false;
4575
4576 if (!(btn->GetWindowStyle() & wxNO_BORDER)) {
4577 btn->SetWindowStyle(btn->GetWindowStyle() | wxNO_BORDER);
4578 highlited = true;
4579 }
4580
4581 auto mark_button = [this, btn, highlited](const bool mark) {
4582 btn->SetBackgroundColour(mark ? m_color_selected_btn_bg : highlited ? m_color_highlight_default : m_color_window_default);
4583 btn->SetForegroundColour(mark ? m_color_hovered_btn_label :m_color_default_btn_label);
4584 btn->Refresh();
4585 btn->Update();
4586 };
4587
4588 // hovering
4589 btn->Bind(wxEVT_ENTER_WINDOW, [mark_button](wxMouseEvent& event) { mark_button(true); event.Skip(); });
4590 btn->Bind(wxEVT_LEAVE_WINDOW, [mark_button, btn](wxMouseEvent& event) { mark_button(is_focused(btn->GetHWND())); event.Skip(); });
4591 // focusing
4592 btn->Bind(wxEVT_SET_FOCUS, [mark_button](wxFocusEvent& event) { mark_button(true); event.Skip(); });
4593 btn->Bind(wxEVT_KILL_FOCUS, [mark_button](wxFocusEvent& event) { mark_button(false); event.Skip(); });
4594
4595 is_focused_button = is_focused(btn->GetHWND());
4596 is_default_button = is_default(btn);
4597 mark_button(is_focused_button);
4598 }
4599#endif
4600 }
4601 }
4602
4603 if (Button* btn = dynamic_cast<Button*>(window)) {
4604 if (btn->GetWindowStyleFlag() & wxBU_AUTODRAW)
4605 return;
4606 }
4607
4608
4609 /*if (m_is_dark_mode != dark_mode() )
4610 m_is_dark_mode = dark_mode();*/
4611
4612 if (m_is_dark_mode) {
4613
4614 auto orig_col = window->GetBackgroundColour();
4615 auto bg_col = StateColor::darkModeColorFor(orig_col);
4616 // there are cases where the background color of an item is bright, specifically:
4617 // * the background color of a button: #009688 -- 73
4618 if (bg_col != orig_col) {
4619 window->SetBackgroundColour(bg_col);
4620 }
4621
4622 orig_col = window->GetForegroundColour();
4623 auto fg_col = StateColor::darkModeColorFor(orig_col);
4624 auto fg_l = StateColor::GetLightness(fg_col);
4625
4626 auto color_difference = StateColor::GetColorDifference(bg_col, fg_col);
4627
4628 // fallback and sanity check with LAB
4629 // color difference of less than 2 or 3 is not normally visible, and even less than 30-40 doesn't stand out
4630 if (color_difference < 10) {
4631 fg_col = StateColor::SetLightness(fg_col, 90);
4632 }
4633 // some of the stock colors have a lightness of ~49
4634 if (fg_l < 45) {
4635 fg_col = StateColor::SetLightness(fg_col, 70);
4636 }
4637 // at this point it shouldn't be possible that fg_col is the same as bg_col, but let's be safe
4638 if (fg_col == bg_col) {
4639 fg_col = StateColor::SetLightness(fg_col, 70);
4640 }
4641
4642 window->SetForegroundColour(fg_col);
4643 }
4644 else {
4645 auto original_col = window->GetBackgroundColour();
4646 auto bg_col = StateColor::lightModeColorFor(original_col);
4647
4648 if (bg_col != original_col) {
4649 window->SetBackgroundColour(bg_col);
4650 }
4651
4652 original_col = window->GetForegroundColour();
4653 auto fg_col = StateColor::lightModeColorFor(original_col);
4654
4655 if (fg_col != original_col) {
4656 window->SetForegroundColour(fg_col);
4657 }
4658 }
4659}
class WXDLLIMPEXP_FWD_CORE wxButton
Definition ProgressDialog.hpp:27
static wxColour lightModeColorFor(wxColour const &color)
Definition StateColor.cpp:211
static wxColour darkModeColorFor(wxColour const &color)
Definition StateColor.cpp:219
static double GetColorDifference(const wxColour &c1, const wxColour &c2)
Definition StateColor.cpp:95
static double GetLightness(const wxColour &color)
Definition StateColor.cpp:99
static wxColour SetLightness(const wxColour &color, double lightness)
Definition StateColor.cpp:105
wxMouseEvent
Definition CameraPopup.cpp:47

References StateColor::darkModeColorFor(), StateColor::GetColorDifference(), StateColor::GetLightness(), StateColor::lightModeColorFor(), m_color_default_btn_label, m_color_highlight_default, m_color_hovered_btn_label, m_color_selected_btn_bg, m_color_window_default, m_is_dark_mode, StateColor::SetLightness(), UpdateDarkUI(), and Slic3r::GUI::wxMouseEvent.

Referenced by UpdateDarkUI(), and UpdateDVCDarkUI().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateDarkUIWin()

void Slic3r::GUI::GUI_App::UpdateDarkUIWin ( wxWindow * win)
4682{
4684}

References Slic3r::GUI::update_dark_children_ui(), and UpdateDarkUIWin().

Referenced by UpdateDarkUIWin().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateDlgDarkUI()

void Slic3r::GUI::GUI_App::UpdateDlgDarkUI ( wxDialog * dlg)
4693{
4694#ifdef __WINDOWS__
4695 NppDarkMode::SetDarkExplorerTheme(dlg->GetHWND());
4696 NppDarkMode::SetDarkTitleBar(dlg->GetHWND());
4697#endif
4699}

References NppDarkMode::SetDarkExplorerTheme(), NppDarkMode::SetDarkTitleBar(), Slic3r::GUI::update_dark_children_ui(), and UpdateDlgDarkUI().

Referenced by UpdateDlgDarkUI().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateDVCDarkUI()

void Slic3r::GUI::GUI_App::UpdateDVCDarkUI ( wxDataViewCtrl * dvc,
bool highlited = false )
4711{
4712#ifdef __WINDOWS__
4713 UpdateDarkUI(dvc, highlited ? dark_mode() : false);
4714#ifdef _MSW_DARK_MODE
4715 //dvc->RefreshHeaderDarkMode(&m_normal_font);
4716 HWND hwnd;
4717 if (!dvc->HasFlag(wxDV_NO_HEADER)) {
4718 hwnd = (HWND) dvc->GenericGetHeader()->GetHandle();
4719 hwnd = GetWindow(hwnd, GW_CHILD);
4720 if (hwnd != NULL)
4722 wxItemAttr attr;
4723 attr.SetTextColour(NppDarkMode::GetTextColor());
4724 attr.SetFont(m_normal_font);
4725 dvc->SetHeaderAttr(attr);
4726 }
4727#endif //_MSW_DARK_MODE
4728 if (dvc->HasFlag(wxDV_ROW_LINES))
4729 dvc->SetAlternateRowColour(m_color_highlight_default);
4730 if (dvc->GetBorder() != wxBORDER_SIMPLE)
4731 dvc->SetWindowStyle(dvc->GetWindowStyle() | wxBORDER_SIMPLE);
4732#endif
4733}
void UpdateDarkUI(wxWindow *window, bool highlited=false, bool just_font=false)
Definition GUI_App.cpp:4565
void SetDarkListViewHeader(HWND hHeader)
Definition dark_mode.cpp:388
COLORREF GetTextColor()
Definition dark_mode.cpp:85

References dark_mode(), NppDarkMode::GetTextColor(), m_color_highlight_default, m_normal_font, NppDarkMode::SetDarkListViewHeader(), UpdateDarkUI(), and UpdateDVCDarkUI().

Referenced by UpdateDVCDarkUI().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateFrameDarkUI()

void Slic3r::GUI::GUI_App::UpdateFrameDarkUI ( wxFrame * dlg)
4702{
4703#ifdef __WINDOWS__
4704 NppDarkMode::SetDarkExplorerTheme(dlg->GetHWND());
4705 NppDarkMode::SetDarkTitleBar(dlg->GetHWND());
4706#endif
4708}

References NppDarkMode::SetDarkExplorerTheme(), NppDarkMode::SetDarkTitleBar(), Slic3r::GUI::update_dark_children_ui(), and UpdateFrameDarkUI().

Referenced by UpdateFrameDarkUI().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ updating_bambu_networking()

int Slic3r::GUI::GUI_App::updating_bambu_networking ( )
private
2224{
2225 DownloadProgressDialog dlg(_L("Downloading Bambu Network Plug-in"));
2226 dlg.ShowModal();
2227 return 0;
2228}

References _L, and Slic3r::GUI::DPIAware< P >::ShowModal().

Here is the call graph for this function:

◆ url_decode()

std::string Slic3r::GUI::GUI_App::url_decode ( std::string value)
9830 {
9831 return Http::url_decode(value);
9832}
static std::string url_decode(const std::string &str)
Definition Http.cpp:984

References url_decode(), and Slic3r::Http::url_decode().

Referenced by handle_web_request(), and url_decode().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ url_encode()

std::string Slic3r::GUI::GUI_App::url_encode ( std::string value)
9834 {
9835 return Http::url_encode(value);
9836}
static std::string url_encode(const std::string &str)
Definition Http.cpp:969

References url_encode(), and Slic3r::Http::url_encode().

Referenced by open_mall_page_dialog(), open_publish_page_dialog(), and url_encode().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ use_legacy_network_plugin()

bool Slic3r::GUI::GUI_App::use_legacy_network_plugin ( ) const
2268{
2269 return app_config && BBLNetworkPlugin::is_legacy_version(app_config->get_network_plugin_version());
2270}
static bool is_legacy_version(const std::string &version)
Definition BBLNetworkPlugin.hpp:301

References app_config, and Slic3r::BBLNetworkPlugin::is_legacy_version().

Referenced by check_networking_version(), download_plugin(), get_plugin_url(), and on_init_inner().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ wait_for_network_idle()

bool Slic3r::GUI::GUI_App::wait_for_network_idle ( int timeout_ms)
private
1950{
1951 const auto deadline = std::chrono::steady_clock::now() +
1952 std::chrono::milliseconds(timeout_ms);
1953
1954 while (std::chrono::steady_clock::now() < deadline) {
1955 if (!m_agent) {
1956 return true; // Agent already gone
1957 }
1958
1959 // Verify all operations completed
1960 bool server_disconnected = !m_agent->is_server_connected();
1961
1962 if (server_disconnected) {
1963 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": network is idle";
1964 return true;
1965 }
1966
1967 // Process events while waiting
1968 if (wxTheApp) {
1969 wxTheApp->ProcessPendingEvents();
1970 }
1971
1972 std::this_thread::sleep_for(std::chrono::milliseconds(POLL_INTERVAL_MS));
1973 }
1974
1975 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": timeout after " << timeout_ms
1976 << "ms, server_connected=" << (m_agent ? m_agent->is_server_connected() : false);
1977 return false;
1978}

References m_agent.

Referenced by hot_reload_network_plugin().

Here is the caller graph for this function:

◆ window_pos_center()

void Slic3r::GUI::GUI_App::window_pos_center ( wxTopLevelWindow * window)
private
10147{
10148 /*unsigned*/int display_idx = wxDisplay::GetFromWindow(window);
10149 wxRect display;
10150 if (display_idx == wxNOT_FOUND) {
10151 display = wxDisplay(0u).GetClientArea();
10152 window->Move(display.GetTopLeft());
10153 } else {
10154 display = wxDisplay(display_idx).GetClientArea();
10155 }
10156
10157 auto metrics = WindowMetrics::from_window(window);
10158 metrics.center_for_display(display);
10159 if (window->GetScreenRect() != metrics.get_rect()) {
10160 window->SetSize(metrics.get_rect());
10161 }
10162}
static WindowMetrics from_window(wxTopLevelWindow *window)
Definition GUI_Utils.cpp:399

References Slic3r::GUI::WindowMetrics::from_window(), and window_pos_center().

Referenced by persist_window_geometry(), and window_pos_center().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ window_pos_restore()

bool Slic3r::GUI::GUI_App::window_pos_restore ( wxTopLevelWindow * window,
const std::string & name,
bool default_maximized = false )
private
10101{
10102 if (name.empty()) { return false; }
10103 const auto config_key = (boost::format("window_%1%") % name).str();
10104
10105 if (! app_config->has(config_key)) {
10106 //window->Maximize(default_maximized);
10107 return false;
10108 }
10109
10110 auto metrics = WindowMetrics::deserialize(app_config->get(config_key));
10111 if (! metrics) {
10112 window->Maximize(default_maximized);
10113 return true;
10114 }
10115
10116 const wxRect& rect = metrics->get_rect();
10117#if defined(__WXGTK__)
10118 // On Wayland, SetPosition() is a no-op for top-level windows.
10119 // Only restore size and maximize state.
10120 if (!Slic3r::GUI::is_running_on_wayland())
10121#endif
10122 window->SetPosition(rect.GetPosition());
10123 window->SetSize(rect.GetSize());
10124 window->Maximize(metrics->get_maximized());
10125 return true;
10126}

References app_config, Slic3r::GUI::WindowMetrics::deserialize(), and window_pos_restore().

Referenced by persist_window_geometry(), and window_pos_restore().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ window_pos_sanitize()

void Slic3r::GUI::GUI_App::window_pos_sanitize ( wxTopLevelWindow * window)
private
10129{
10130 /*unsigned*/int display_idx = wxDisplay::GetFromWindow(window);
10131 wxRect display;
10132 if (display_idx == wxNOT_FOUND) {
10133 display = wxDisplay(0u).GetClientArea();
10134 window->Move(display.GetTopLeft());
10135 } else {
10136 display = wxDisplay(display_idx).GetClientArea();
10137 }
10138
10139 auto metrics = WindowMetrics::from_window(window);
10140 metrics.sanitize_for_display(display);
10141 if (window->GetScreenRect() != metrics.get_rect()) {
10142 window->SetSize(metrics.get_rect());
10143 }
10144}

References Slic3r::GUI::WindowMetrics::from_window(), and window_pos_sanitize().

Referenced by persist_window_geometry(), and window_pos_sanitize().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ window_pos_save()

void Slic3r::GUI::GUI_App::window_pos_save ( wxTopLevelWindow * window,
const std::string & name )
private
10091{
10092 if (name.empty()) { return; }
10093 const auto config_key = (boost::format("window_%1%") % name).str();
10094
10095 WindowMetrics metrics = WindowMetrics::from_window(window);
10096 app_config->set(config_key, metrics.serialize());
10097 app_config->save();
10098}

References app_config, Slic3r::GUI::WindowMetrics::from_window(), Slic3r::GUI::WindowMetrics::serialize(), and window_pos_save().

Referenced by persist_window_geometry(), and window_pos_save().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ app_config

AppConfig* Slic3r::GUI::GUI_App::app_config { nullptr }
787{ nullptr };

Referenced by GUI_App(), ~GUI_App(), Slic3r::anonymous_namespace{PluginHostApp.cpp}::app_info(), Slic3r::anonymous_namespace{PluginHostPresets.cpp}::bind_filament_target(), Slic3r::GUI::anonymous_namespace{NativeCommands.cpp}::build_command_catalog(), check_and_keep_current_preset_changes(), check_and_save_current_preset_changes(), check_legacy_user_filament_presets(), check_networking_version(), check_new_version(), check_new_version_sf(), check_privacy_update(), check_privacy_version(), check_updates(), copy_network_if_available(), disassociate_files(), download_plugin(), enable_developer_mode(), enable_user_preset_folder(), focus_mode(), get_mode(), get_plugin_url(), get_saved_mode(), Slic3r::GUI::GUI_Run(), handle_web_request(), has_model_mall(), hot_reload_network_plugin(), import_model(), import_zip(), init_app_config(), init_download_path(), install_network_plugin_from_ota(), install_plugin(), is_enable_multi_machine(), link_to_lan_only_wiki(), link_to_network_check(), Slic3r::anonymous_namespace{PluginHostPresets.cpp}::list_bundle_ids(), load_gcode(), load_language(), load_pending_vendors(), load_project(), migrate_network_plugin_config(), on_init_inner(), on_init_network(), on_shortcuts_changed(), on_user_login_handle(), open_mall_page_dialog(), open_preferences(), open_publish_page_dialog(), post_init(), Slic3r::anonymous_namespace{PluginHostPresets.cpp}::reload_local_bundle(), reload_settings(), remove_user_presets(), restart_networking(), Slic3r::GUI::ConfigWizard::run(), Slic3r::GUI::GuideFrame::run(), save_mode(), scan_orphaned_info_files(), set_auto_toolbar_icon_scale(), set_mode(), set_skip_version(), show_3d_navigator(), show_canvas_zoom_button(), show_center_of_mass(), show_check_privacy_dlg(), show_network_plugin_download_dialog(), show_outline(), show_plate_gridlines(), start_download(), start_sync_user_preset(), starts_on_prepare(), sync_bundle(), toggle_canvas_zoom_button(), toggle_focus_mode(), toggle_show_3d_navigator(), toggle_show_center_of_mass(), toggle_show_gcode_window(), toggle_show_outline(), toggle_show_plate_gridlines(), toolbar_icon_scale(), update_label_colours_from_appconfig(), update_single_bundle(), use_legacy_network_plugin(), window_pos_restore(), and window_pos_save().

◆ hms_query

HMSQuery* Slic3r::GUI::GUI_App::hms_query { nullptr }
private
350{ nullptr };

Referenced by get_hms_query(), post_init(), and recreate_GUI().

◆ init_params

GUI_InitParams* Slic3r::GUI::GUI_App::init_params { nullptr }
785{ nullptr };

Referenced by Slic3r::GUI::GUI_Run(), init_glcontext(), on_init_inner(), and post_init().

◆ last_active_point

std::chrono::system_clock::time_point Slic3r::GUI::GUI_App::last_active_point

◆ login_dlg

ZUserLogin* Slic3r::GUI::GUI_App::login_dlg { nullptr }
private
345{ nullptr };

Referenced by request_cloud_web_session(), ShowUserLogin(), and shutdown().

◆ m_action_registry

ActionRegistry Slic3r::GUI::GUI_App::m_action_registry

◆ m_active_language_code

wxString Slic3r::GUI::GUI_App::m_active_language_code
private

◆ m_adding_script_handler

bool Slic3r::GUI::GUI_App::m_adding_script_handler { false }
private

◆ m_agent

◆ m_app_conf_exists

bool Slic3r::GUI::GUI_App::m_app_conf_exists { false }
private
268{ false };

Referenced by check_updates(), config_wizard_startup(), and init_app_config().

◆ m_app_mode

EAppMode Slic3r::GUI::GUI_App::m_app_mode { EAppMode::Editor }
private

◆ m_bold_font

wxFont Slic3r::GUI::GUI_App::m_bold_font
private

Referenced by bold_font(), init_fonts(), and update_fonts().

◆ m_check_network_thread

boost::thread Slic3r::GUI::GUI_App::m_check_network_thread
private

◆ m_cloud_handoff_gen

uint64_t Slic3r::GUI::GUI_App::m_cloud_handoff_gen { 0 }
private

◆ m_cloud_handoff_state

std::string Slic3r::GUI::GUI_App::m_cloud_handoff_state
private

◆ m_cloud_open_path

std::string Slic3r::GUI::GUI_App::m_cloud_open_path
private

◆ m_code_font

wxFont Slic3r::GUI::GUI_App::m_code_font
private

Referenced by code_font(), init_fonts(), and update_fonts().

◆ m_color_default_btn_label

wxColour Slic3r::GUI::GUI_App::m_color_default_btn_label
private

Referenced by init_label_colours(), and UpdateDarkUI().

◆ m_color_highlight_default

wxColour Slic3r::GUI::GUI_App::m_color_highlight_default
private

◆ m_color_highlight_label_default

wxColour Slic3r::GUI::GUI_App::m_color_highlight_label_default
private

◆ m_color_hovered_btn_label

wxColour Slic3r::GUI::GUI_App::m_color_hovered_btn_label
private

◆ m_color_label_default

wxColour Slic3r::GUI::GUI_App::m_color_label_default
private

◆ m_color_label_modified

wxColour Slic3r::GUI::GUI_App::m_color_label_modified
private

◆ m_color_label_sys

wxColour Slic3r::GUI::GUI_App::m_color_label_sys
private

◆ m_color_selected_btn_bg

wxColour Slic3r::GUI::GUI_App::m_color_selected_btn_bg
private

◆ m_color_window_default

wxColour Slic3r::GUI::GUI_App::m_color_window_default
private

◆ m_config_corrupted

bool Slic3r::GUI::GUI_App::m_config_corrupted { false }
private
913{ false };

Referenced by init_app_config(), and on_init_inner().

◆ m_create_preset_blocked

std::vector<bool> Slic3r::GUI::GUI_App::m_create_preset_blocked { false, false, false, false, false, false }
private
329{ false, false, false, false, false, false }; // excceed limit

Referenced by process_delete_presets(), and sync_preset().

◆ m_datadir_redefined

bool Slic3r::GUI::GUI_App::m_datadir_redefined { false }
private
909{ false };

Referenced by init_app_config().

◆ m_device_manager

◆ m_downloader

std::unique_ptr<Downloader> Slic3r::GUI::GUI_App::m_downloader
private

Referenced by GUI_App(), downloader(), and start_download().

◆ m_em_unit

int Slic3r::GUI::GUI_App::m_em_unit
private

◆ m_filament_color_code_query

FilamentColorCodeQuery* Slic3r::GUI::GUI_App::m_filament_color_code_query { nullptr }
private
351{ nullptr };

Referenced by get_filament_color_code_query().

◆ m_force_colors_update

bool Slic3r::GUI::GUI_App::m_force_colors_update { false }
private
290{ false };

Referenced by force_colors_update(), and update_ui_from_settings().

◆ m_http_server

HttpServer Slic3r::GUI::GUI_App::m_http_server
private

◆ m_imgui

std::unique_ptr<ImGuiWrapper> Slic3r::GUI::GUI_App::m_imgui
private

Referenced by GUI_App(), imgui(), and load_language().

◆ m_info_dialog_content

wxString Slic3r::GUI::GUI_App::m_info_dialog_content
private

◆ m_init_app_config_from_older

bool Slic3r::GUI::GUI_App::m_init_app_config_from_older { false }
private
908{ false };

Referenced by on_init_inner().

◆ m_initialized

bool Slic3r::GUI::GUI_App::m_initialized { false }
private
266{ false };

Referenced by initialized(), and on_init_inner().

◆ m_instance_hash_int

size_t Slic3r::GUI::GUI_App::m_instance_hash_int
private

◆ m_instance_hash_string

std::string Slic3r::GUI::GUI_App::m_instance_hash_string
private

◆ m_is_closing

std::atomic<bool> Slic3r::GUI::GUI_App::m_is_closing {false}
private
323{false};

Referenced by is_closing(), set_closing(), and start_sync_user_preset().

◆ m_is_dark_mode

bool Slic3r::GUI::GUI_App::m_is_dark_mode { false }
private
362{ false };

Referenced by Update_dark_mode_flag(), and UpdateDarkUI().

◆ m_is_recreating_gui

bool Slic3r::GUI::GUI_App::m_is_recreating_gui { false }
private
270{ false };

Referenced by is_recreating_gui(), recreate_GUI(), and shutdown().

◆ m_language_info_best

const wxLanguageInfo* Slic3r::GUI::GUI_App::m_language_info_best = nullptr
private

Referenced by load_language().

◆ m_language_info_system

const wxLanguageInfo* Slic3r::GUI::GUI_App::m_language_info_system = nullptr
private

Referenced by load_language().

◆ m_last_401_error_time

std::chrono::steady_clock::time_point Slic3r::GUI::GUI_App::m_last_401_error_time
private

◆ m_last_config_version

boost::optional<Semver> Slic3r::GUI::GUI_App::m_last_config_version
private

◆ m_last_input

std::chrono::steady_clock::time_point Slic3r::GUI::GUI_App::m_last_input { std::chrono::steady_clock::now() }
private
271{ std::chrono::steady_clock::now() };

Referenced by FilterEvent(), and input_idle_ms().

◆ m_legacy_filament_check_due

bool Slic3r::GUI::GUI_App::m_legacy_filament_check_due {false}
private
359{false}; // the startup check waits for that pull

Referenced by check_legacy_user_filament_presets(), and start_sync_user_preset().

◆ m_legacy_filament_check_running

bool Slic3r::GUI::GUI_App::m_legacy_filament_check_running {false}
private
360{false}; // a check is in progress, its dialog may be open

Referenced by check_legacy_user_filament_presets().

◆ m_link_font

wxFont Slic3r::GUI::GUI_App::m_link_font
private

Referenced by link_font(), and update_fonts().

◆ m_mall_model_download_name

std::string Slic3r::GUI::GUI_App::m_mall_model_download_name

◆ m_mall_model_download_url

std::string Slic3r::GUI::GUI_App::m_mall_model_download_url

◆ m_mall_publish_dialog

ModelMallDialog* Slic3r::GUI::GUI_App::m_mall_publish_dialog { nullptr }
755{ nullptr };

Referenced by remove_mall_system_dialog(), and remove_ping_bind_dialog().

◆ m_migration_retry_pending

std::atomic<bool> Slic3r::GUI::GUI_App::m_migration_retry_pending {false}
private
361{false};

Referenced by maybe_migrate_user_presets_on_login().

◆ m_networking_cancel_update

bool Slic3r::GUI::GUI_App::m_networking_cancel_update { false }
private

◆ m_networking_compatible

bool Slic3r::GUI::GUI_App::m_networking_compatible { false }
private

◆ m_networking_need_update

bool Slic3r::GUI::GUI_App::m_networking_need_update { false }
private
332{ false };

Referenced by on_init_network(), and post_init().

◆ m_normal_font

wxFont Slic3r::GUI::GUI_App::m_normal_font
private

◆ m_older_data_dir_path

std::string Slic3r::GUI::GUI_App::m_older_data_dir_path
private

Referenced by copy_older_config().

◆ m_open_method

std::string Slic3r::GUI::GUI_App::m_open_method
private

Referenced by post_init().

◆ m_opengl_mgr

◆ m_other_instance_message_handler

std::unique_ptr<OtherInstanceMessageHandler> Slic3r::GUI::GUI_App::m_other_instance_message_handler
private

◆ m_pending_conflict_setting_ids

std::vector<std::string> Slic3r::GUI::GUI_App::m_pending_conflict_setting_ids
private

◆ m_ping_code_binding_dialog

PingCodeBindDialog* Slic3r::GUI::GUI_App::m_ping_code_binding_dialog { nullptr }
756{ nullptr };

Referenced by popup_ping_bind_dialog(), and remove_ping_bind_dialog().

◆ m_plugins_dlg

PluginsDialog* Slic3r::GUI::GUI_App::m_plugins_dlg {nullptr}

◆ m_post_initialized

bool Slic3r::GUI::GUI_App::m_post_initialized { false }
private
267{ false };

Referenced by on_init_inner(), and post_init().

◆ m_preset_bundle_dlg

PresetBundleDialog* Slic3r::GUI::GUI_App::m_preset_bundle_dlg {nullptr}

◆ m_printhost_job_queue

std::unique_ptr<PrintHostJobQueue> Slic3r::GUI::GUI_App::m_printhost_job_queue
private

◆ m_removable_drive_manager

std::unique_ptr<RemovableDriveManager> Slic3r::GUI::GUI_App::m_removable_drive_manager
private

◆ m_restart_sync_pending

std::atomic<bool> Slic3r::GUI::GUI_App::m_restart_sync_pending {false}
private
355{false};

Referenced by restart_sync_user_preset().

◆ m_server_error_dialog

NetworkErrorDialog* Slic3r::GUI::GUI_App::m_server_error_dialog { nullptr }
758{ nullptr };

◆ m_shortcuts

std::unique_ptr<ShortcutRegistry> Slic3r::GUI::GUI_App::m_shortcuts
private

◆ m_show_error_msgdlg

bool Slic3r::GUI::GUI_App::m_show_error_msgdlg {false}
private
374{false};

Referenced by process_network_msg().

◆ m_show_gcode_window

bool Slic3r::GUI::GUI_App::m_show_gcode_window {true}
private

◆ m_show_http_error_msgdlg

bool Slic3r::GUI::GUI_App::m_show_http_error_msgdlg {false}
private
365{false};

Referenced by on_http_error().

◆ m_side_popup_status

bool Slic3r::GUI::GUI_App::m_side_popup_status {false}
private

◆ m_single_instance_checker

std::unique_ptr<wxSingleInstanceChecker> Slic3r::GUI::GUI_App::m_single_instance_checker
private

◆ m_small_font

wxFont Slic3r::GUI::GUI_App::m_small_font
private

◆ m_speed_dial_dialog

SpeedDialWebDialog* Slic3r::GUI::GUI_App::m_speed_dial_dialog {nullptr}
646{nullptr};

Referenced by open_speed_dial(), and recreate_GUI().

◆ m_studio_active

bool Slic3r::GUI::GUI_App::m_studio_active = true

Referenced by on_init_inner().

◆ m_sync_update_thread

boost::thread Slic3r::GUI::GUI_App::m_sync_update_thread
private

◆ m_sync_user_preset_dlg_active

std::atomic<bool> Slic3r::GUI::GUI_App::m_sync_user_preset_dlg_active {false}
private
356{false}; // a manual "Sync Presets" progress dialog is on screen (see restart_sync_user_preset)

Referenced by restart_sync_user_preset(), and start_sync_user_preset().

◆ m_sync_user_presets_now

std::atomic<bool> Slic3r::GUI::GUI_App::m_sync_user_presets_now {false}
private
357{false}; // request the sync loop to push user presets on its next tick

Referenced by check_legacy_user_filament_presets(), force_push_conflicting_preset(), and start_sync_user_preset().

◆ m_task_manager

Slic3r::TaskManager* Slic3r::GUI::GUI_App::m_task_manager { nullptr }
private
326{ nullptr };

Referenced by getTaskManager(), and on_init_network().

◆ m_terminal_dlg

TerminalDialog* Slic3r::GUI::GUI_App::m_terminal_dlg {nullptr}
647{nullptr};

Referenced by open_terminal_dialog().

◆ m_unsigned_plugin_warning_shown

bool Slic3r::GUI::GUI_App::m_unsigned_plugin_warning_shown { false }
private
911{ false };

Referenced by process_network_msg(), and reset_unsigned_plugin_warning().

◆ m_upgrade_network_job

std::shared_ptr<UpgradeNetworkJob> Slic3r::GUI::GUI_App::m_upgrade_network_job
private

◆ m_user_manager

Slic3r::UserManager* Slic3r::GUI::GUI_App::m_user_manager { nullptr }
private
325{ nullptr };

Referenced by on_init_network(), and OnExit().

◆ m_user_preset_pull_pending

bool Slic3r::GUI::GUI_App::m_user_preset_pull_pending {false}
private
358{false}; // set when a sync thread starts, cleared once its pull is applied; a failed pull or a stopped sync leaves it set

Referenced by check_legacy_user_filament_presets(), and start_sync_user_preset().

◆ m_user_sync_token

std::shared_ptr<int> Slic3r::GUI::GUI_App::m_user_sync_token
private

◆ m_wxLocale

std::unique_ptr<wxLocale> Slic3r::GUI::GUI_App::m_wxLocale
private

◆ mainframe

◆ model_tabs_list

std::vector<Tab *> Slic3r::GUI::GUI_App::model_tabs_list

◆ need_add_filaments

std::map<std::string, std::string> Slic3r::GUI::GUI_App::need_add_filaments
private

◆ need_add_vendors

std::map<std::string, std::map<std::string, std::set<std::string> > > Slic3r::GUI::GUI_App::need_add_vendors
private

◆ need_delete_presets

std::map<std::string, std::string> Slic3r::GUI::GUI_App::need_delete_presets
private

◆ plate_tab

Tab* Slic3r::GUI::GUI_App::plate_tab

Referenced by get_plate_tab().

◆ plater_

◆ preset_bundle

PresetBundle* Slic3r::GUI::GUI_App::preset_bundle { nullptr }
788{ nullptr };

Referenced by ~GUI_App(), apply_keeped_preset_modifications(), Slic3r::anonymous_namespace{PluginHostPresets.cpp}::bind_filament_target(), Slic3r::anonymous_namespace{PluginHostPresets.cpp}::bind_preset_target(), check_and_keep_current_preset_changes(), check_and_save_current_preset_changes(), check_bundle_updates(), check_legacy_user_filament_presets(), check_preset_parent_available(), check_printer_presets(), Slic3r::anonymous_namespace{PluginHostPresets.cpp}::PresetTransaction::commit(), config_wizard_startup(), copy_older_config(), extruders_cnt(), extruders_edited_cnt(), filaments_cnt(), force_push_conflicting_preset(), get_printer_cloud_provider(), get_selected_presets(), global_print_sequence(), has_current_preset_changes(), has_unsaved_preset_changes(), is_blocking_printing(), Slic3r::anonymous_namespace{PluginHostPresets.cpp}::list_bundle_ids(), load_current_presets(), load_pending_vendors(), maybe_migrate_user_presets_on_login(), on_http_error(), on_init_inner(), on_user_login_handle(), post_init(), Slic3r::anonymous_namespace{PluginHostPresets.cpp}::reload_local_bundle(), reload_settings(), remove_user_presets(), request_user_logout(), Slic3r::anonymous_namespace{PluginHostPresets.cpp}::require_gui_app(), Slic3r::anonymous_namespace{PluginHostPresets.cpp}::require_tab(), Slic3r::GUI::ProjectDirtyStateManager::reset_initial_presets(), resolve_printer_agent_id(), restart_networking(), Slic3r::GUI::ConfigWizard::run(), Slic3r::GUI::GuideFrame::run(), select_machine(), start_sync_user_preset(), switch_printer_agent(), switch_printer_agent_if_pending(), sync_bundle(), sync_preset(), Slic3r::GUI::ProjectDirtyStateManager::update_from_presets(), update_saved_preset_from_current_preset(), and update_single_bundle().

◆ preset_updater

◆ privacy_version_info

VersionInfo Slic3r::GUI::GUI_App::privacy_version_info
private

◆ tabs_list

◆ test_url_state

std::map<std::string, bool> Slic3r::GUI::GUI_App::test_url_state

◆ version_display

std::string Slic3r::GUI::GUI_App::version_display = ""
staticprivate

Referenced by format_display_version().

◆ version_info


The documentation for this class was generated from the following files:
  • /home/runner/work/OrcaSlicer/OrcaSlicer/src/slic3r/GUI/GUI_App.hpp
  • /home/runner/work/OrcaSlicer/OrcaSlicer/src/slic3r/GUI/GUI_App.cpp