2018-09-20 06:40:22 +00:00
# include "MainFrame.hpp"
# include <wx/panel.h>
# include <wx/notebook.h>
# include <wx/icon.h>
# include <wx/sizer.h>
# include <wx/menu.h>
# include <wx/progdlg.h>
2018-09-21 13:42:31 +00:00
# include <wx/tooltip.h>
2018-10-18 13:13:38 +00:00
# include <wx/glcanvas.h>
2018-10-03 14:27:02 +00:00
# include <wx/debug.h>
2018-09-20 06:40:22 +00:00
2019-01-09 09:43:17 +00:00
# include <boost/algorithm/string/predicate.hpp>
2018-11-26 13:41:58 +00:00
# include "libslic3r/Print.hpp"
# include "libslic3r/Polygon.hpp"
2018-09-20 06:40:22 +00:00
# include "Tab.hpp"
# include "PresetBundle.hpp"
# include "ProgressStatusBar.hpp"
# include "3DScene.hpp"
# include "AppConfig.hpp"
2018-12-14 14:27:34 +00:00
# include "PrintHostDialogs.hpp"
2018-10-17 10:17:25 +00:00
# include "wxExtensions.hpp"
2019-01-30 09:05:54 +00:00
# include "GUI_ObjectList.hpp"
2018-11-26 13:41:58 +00:00
# include "I18N.hpp"
2018-09-20 06:40:22 +00:00
# include <fstream>
2018-09-20 23:33:41 +00:00
# include "GUI_App.hpp"
2018-09-20 06:40:22 +00:00
namespace Slic3r {
2018-09-20 23:33:41 +00:00
namespace GUI {
2018-12-19 16:38:41 +00:00
MainFrame : : MainFrame ( ) :
2019-01-11 17:09:21 +00:00
wxFrame ( NULL , wxID_ANY , SLIC3R_BUILD , wxDefaultPosition , wxDefaultSize , wxDEFAULT_FRAME_STYLE , " mainframe " ) ,
2018-12-14 14:27:34 +00:00
m_printhost_queue_dlg ( new PrintHostQueueDialog ( this ) )
2018-09-20 06:40:22 +00:00
{
2018-09-24 12:27:03 +00:00
// Load the icon either from the exe, or from the ico file.
# if _WIN32
{
TCHAR szExeFileName [ MAX_PATH ] ;
GetModuleFileName ( nullptr , szExeFileName , MAX_PATH ) ;
SetIcon ( wxIcon ( szExeFileName , wxBITMAP_TYPE_ICO ) ) ;
}
# else
2018-09-20 23:33:41 +00:00
SetIcon ( wxIcon ( Slic3r : : var ( " Slic3r_128px.png " ) , wxBITMAP_TYPE_PNG ) ) ;
2018-09-24 12:27:03 +00:00
# endif // _WIN32
2018-09-20 06:40:22 +00:00
2018-12-04 10:14:39 +00:00
// initialize status bar
m_statusbar = new ProgressStatusBar ( this ) ;
m_statusbar - > embed ( this ) ;
2019-01-21 11:34:28 +00:00
m_statusbar - > set_status_text ( _ ( L ( " Version " ) ) + " " +
2018-12-04 10:14:39 +00:00
SLIC3R_VERSION +
_ ( L ( " - Remember to check for updates at http://github.com/prusa3d/slic3r/releases " ) ) ) ;
2018-09-20 06:40:22 +00:00
// initialize tabpanel and menubar
2018-09-20 23:33:41 +00:00
init_tabpanel ( ) ;
init_menubar ( ) ;
2018-09-20 06:40:22 +00:00
// set default tooltip timer in msec
// SetAutoPop supposedly accepts long integers but some bug doesn't allow for larger values
// (SetAutoPop is not available on GTK.)
2018-09-20 23:33:41 +00:00
wxToolTip : : SetAutoPop ( 32767 ) ;
2018-09-20 06:40:22 +00:00
2018-09-20 23:33:41 +00:00
m_loaded = true ;
// initialize layout
auto sizer = new wxBoxSizer ( wxVERTICAL ) ;
if ( m_tabpanel )
sizer - > Add ( m_tabpanel , 1 , wxEXPAND ) ;
sizer - > SetSizeHints ( this ) ;
SetSizer ( sizer ) ;
Fit ( ) ;
2019-01-21 16:36:25 +00:00
# ifdef __APPLE__
// Using SetMinSize() on Mac messes up the window position in some cases
// cf. https://groups.google.com/forum/#!topic/wx-users/yUKPBBfXWO0
SetSize ( wxSize ( 760 , 490 ) ) ;
# else
2018-09-20 23:33:41 +00:00
SetMinSize ( wxSize ( 760 , 490 ) ) ;
SetSize ( GetMinSize ( ) ) ;
2019-01-21 16:36:25 +00:00
# endif
2018-09-20 23:33:41 +00:00
Layout ( ) ;
2018-09-20 06:40:22 +00:00
// declare events
2018-10-31 11:56:08 +00:00
Bind ( wxEVT_CLOSE_WINDOW , [ this ] ( wxCloseEvent & event ) {
2018-09-20 23:33:41 +00:00
if ( event . CanVeto ( ) & & ! wxGetApp ( ) . check_unsaved_changes ( ) ) {
event . Veto ( ) ;
return ;
}
2019-01-11 17:09:21 +00:00
2018-09-20 23:33:41 +00:00
// Save the slic3r.ini.Usually the ini file is saved from "on idle" callback,
// but in rare cases it may not have been called yet.
wxGetApp ( ) . app_config - > save ( ) ;
2018-09-20 06:40:22 +00:00
// if (m_plater)
// m_plater->print = undef;
2018-09-20 23:33:41 +00:00
_3DScene : : remove_all_canvases ( ) ;
2018-09-20 06:40:22 +00:00
// Slic3r::GUI::deregister_on_request_update_callback();
2019-01-25 12:16:32 +00:00
2019-01-28 11:12:14 +00:00
// set to null tabs and a platter
2019-01-25 12:16:32 +00:00
// to avoid any manipulations with them from App->wxEVT_IDLE after of the mainframe closing
2019-01-28 11:12:14 +00:00
wxGetApp ( ) . tabs_list . clear ( ) ;
wxGetApp ( ) . plater_ = nullptr ;
2019-01-25 12:16:32 +00:00
2018-09-20 23:33:41 +00:00
// propagate event
event . Skip ( ) ;
} ) ;
2018-09-20 06:40:22 +00:00
2019-01-11 17:09:21 +00:00
wxGetApp ( ) . persist_window_geometry ( this ) ;
2018-10-17 12:01:10 +00:00
2019-01-11 17:09:21 +00:00
update_ui_from_settings ( ) ; // FIXME (?)
2018-09-20 06:40:22 +00:00
}
2019-01-28 11:12:14 +00:00
2018-09-20 06:40:22 +00:00
void MainFrame : : init_tabpanel ( )
{
m_tabpanel = new wxNotebook ( this , wxID_ANY , wxDefaultPosition , wxDefaultSize , wxNB_TOP | wxTAB_TRAVERSAL ) ;
2018-10-31 11:56:08 +00:00
m_tabpanel - > Bind ( wxEVT_NOTEBOOK_PAGE_CHANGED , [ this ] ( wxEvent & ) {
2018-09-20 23:33:41 +00:00
auto panel = m_tabpanel - > GetCurrentPage ( ) ;
2018-10-02 11:23:38 +00:00
if ( panel = = nullptr )
2018-09-17 10:15:11 +00:00
return ;
2018-11-19 12:17:14 +00:00
auto & tabs_list = wxGetApp ( ) . tabs_list ;
if ( find ( tabs_list . begin ( ) , tabs_list . end ( ) , panel ) ! = tabs_list . end ( ) ) {
// On GTK, the wxEVT_NOTEBOOK_PAGE_CHANGED event is triggered
// before the MainFrame is fully set up.
static_cast < Tab * > ( panel ) - > OnActivate ( ) ;
2018-09-20 23:33:41 +00:00
}
} ) ;
2018-09-20 06:40:22 +00:00
2018-12-19 16:38:41 +00:00
m_plater = new Slic3r : : GUI : : Plater ( m_tabpanel , this ) ;
wxGetApp ( ) . plater_ = m_plater ;
m_tabpanel - > AddPage ( m_plater , _ ( L ( " Plater " ) ) ) ;
2018-09-20 06:40:22 +00:00
2019-01-30 09:05:54 +00:00
wxGetApp ( ) . obj_list ( ) - > create_popup_menus ( ) ;
2018-10-09 10:41:05 +00:00
// The following event is emited by Tab implementation on config value change.
Bind ( EVT_TAB_VALUE_CHANGED , & MainFrame : : on_value_changed , this ) ;
2018-09-20 06:40:22 +00:00
2018-10-03 14:27:02 +00:00
// The following event is emited by Tab on preset selection,
2018-09-20 06:40:22 +00:00
// or when the preset's "modified" status changes.
2018-10-03 14:27:02 +00:00
Bind ( EVT_TAB_PRESETS_CHANGED , & MainFrame : : on_presets_changed , this ) ;
2018-09-20 23:33:41 +00:00
create_preset_tabs ( ) ;
2018-09-20 06:40:22 +00:00
if ( m_plater ) {
// load initial config
2018-09-20 23:33:41 +00:00
auto full_config = wxGetApp ( ) . preset_bundle - > full_config ( ) ;
2018-10-17 09:12:38 +00:00
m_plater - > on_config_change ( full_config ) ;
2018-09-20 06:40:22 +00:00
// Show a correct number of filament fields.
2018-10-10 11:53:45 +00:00
// nozzle_diameter is undefined when SLA printer is selected
2018-10-31 11:56:08 +00:00
if ( full_config . has ( " nozzle_diameter " ) ) {
2018-10-10 11:53:45 +00:00
m_plater - > on_extruders_change ( full_config . option < ConfigOptionFloats > ( " nozzle_diameter " ) - > values . size ( ) ) ;
}
2018-09-20 06:40:22 +00:00
}
}
2018-09-20 23:33:41 +00:00
void MainFrame : : create_preset_tabs ( )
{
2018-10-01 13:09:31 +00:00
wxGetApp ( ) . update_label_colours_from_appconfig ( ) ;
2018-09-20 23:33:41 +00:00
add_created_tab ( new TabPrint ( m_tabpanel ) ) ;
add_created_tab ( new TabFilament ( m_tabpanel ) ) ;
2018-11-19 12:17:14 +00:00
add_created_tab ( new TabSLAPrint ( m_tabpanel ) ) ;
2018-09-20 23:33:41 +00:00
add_created_tab ( new TabSLAMaterial ( m_tabpanel ) ) ;
add_created_tab ( new TabPrinter ( m_tabpanel ) ) ;
}
void MainFrame : : add_created_tab ( Tab * panel )
{
2018-10-04 14:43:10 +00:00
panel - > create_preset_tab ( ) ;
2018-11-19 08:15:53 +00:00
2018-11-19 12:17:14 +00:00
const auto printer_tech = wxGetApp ( ) . preset_bundle - > printers . get_edited_preset ( ) . printer_technology ( ) ;
2018-09-20 23:33:41 +00:00
2018-11-19 12:17:14 +00:00
if ( panel - > supports_printer_technology ( printer_tech ) )
2018-09-20 23:33:41 +00:00
m_tabpanel - > AddPage ( panel , panel - > title ( ) ) ;
}
2018-11-15 14:27:39 +00:00
bool MainFrame : : can_save ( ) const
{
return ( m_plater ! = nullptr ) ? ! m_plater - > model ( ) . objects . empty ( ) : false ;
}
bool MainFrame : : can_export_model ( ) const
{
return ( m_plater ! = nullptr ) ? ! m_plater - > model ( ) . objects . empty ( ) : false ;
}
bool MainFrame : : can_export_gcode ( ) const
{
if ( m_plater = = nullptr )
return false ;
if ( m_plater - > model ( ) . objects . empty ( ) )
return false ;
if ( m_plater - > is_export_gcode_scheduled ( ) )
return false ;
// TODO:: add other filters
return true ;
}
2018-11-16 11:31:06 +00:00
2019-01-21 11:34:28 +00:00
bool MainFrame : : can_slice ( ) const
{
bool bg_proc = wxGetApp ( ) . app_config - > get ( " background_processing " ) = = " 1 " ;
return ( m_plater ! = nullptr ) ? ! m_plater - > model ( ) . objects . empty ( ) & & ! bg_proc : false ;
}
2018-11-16 11:31:06 +00:00
bool MainFrame : : can_change_view ( ) const
{
int page_id = m_tabpanel - > GetSelection ( ) ;
2019-01-10 13:45:09 +00:00
return page_id ! = wxNOT_FOUND & & dynamic_cast < const Slic3r : : GUI : : Plater * > ( m_tabpanel - > GetPage ( ( size_t ) page_id ) ) ! = nullptr ;
2018-11-16 11:31:06 +00:00
}
2018-11-21 14:28:35 +00:00
bool MainFrame : : can_select ( ) const
{
return ( m_plater ! = nullptr ) ? ! m_plater - > model ( ) . objects . empty ( ) : false ;
}
2018-11-21 14:47:41 +00:00
bool MainFrame : : can_delete ( ) const
{
return ( m_plater ! = nullptr ) ? ! m_plater - > is_selection_empty ( ) : false ;
}
2018-11-22 10:31:53 +00:00
bool MainFrame : : can_delete_all ( ) const
{
return ( m_plater ! = nullptr ) ? ! m_plater - > model ( ) . objects . empty ( ) : false ;
}
2018-11-15 14:27:39 +00:00
2018-09-20 06:40:22 +00:00
void MainFrame : : init_menubar ( )
{
2019-01-11 16:06:46 +00:00
# ifdef __APPLE__
wxMenuBar : : SetAutoWindowMenu ( false ) ;
# endif
2018-09-20 06:40:22 +00:00
// File menu
2018-09-20 23:33:41 +00:00
wxMenu * fileMenu = new wxMenu ;
2018-09-20 06:40:22 +00:00
{
2019-01-29 13:44:10 +00:00
wxMenuItem * item_open = append_menu_item ( fileMenu , wxID_ANY , _ ( L ( " &Open Project " ) ) + dots + " \t Ctrl+O " , _ ( L ( " Open a project file " ) ) ,
2018-11-15 14:27:39 +00:00
[ this ] ( wxCommandEvent & ) { if ( m_plater ) m_plater - > load_project ( ) ; } , " brick_add.png " ) ;
2019-01-29 13:44:10 +00:00
wxMenuItem * item_save = append_menu_item ( fileMenu , wxID_ANY , _ ( L ( " &Save Project " ) ) + " \t Ctrl+S " , _ ( L ( " Save current project file " ) ) ,
2019-01-02 14:11:05 +00:00
[ this ] ( wxCommandEvent & ) { if ( m_plater ) m_plater - > export_3mf ( into_path ( m_plater - > get_project_filename ( ) ) ) ; } , " disk.png " ) ;
2019-01-29 13:44:10 +00:00
wxMenuItem * item_save_as = append_menu_item ( fileMenu , wxID_ANY , _ ( L ( " Save Project &as " ) ) + dots + " \t Ctrl+Alt+S " , _ ( L ( " Save current project file as " ) ) ,
2018-11-15 14:27:39 +00:00
[ this ] ( wxCommandEvent & ) { if ( m_plater ) m_plater - > export_3mf ( ) ; } , " disk.png " ) ;
fileMenu - > AppendSeparator ( ) ;
wxMenu * import_menu = new wxMenu ( ) ;
2019-01-21 11:34:28 +00:00
wxMenuItem * item_import_model = append_menu_item ( import_menu , wxID_ANY , _ ( L ( " Import STL/OBJ/AM&F/3MF " ) ) + dots + " \t Ctrl+I " , _ ( L ( " Load a model " ) ) ,
2018-11-15 14:27:39 +00:00
[ this ] ( wxCommandEvent & ) { if ( m_plater ) m_plater - > add_model ( ) ; } , " brick_add.png " ) ;
import_menu - > AppendSeparator ( ) ;
2019-01-21 11:34:28 +00:00
append_menu_item ( import_menu , wxID_ANY , _ ( L ( " Import &Config " ) ) + dots + " \t Ctrl+L " , _ ( L ( " Load exported configuration file " ) ) ,
2018-11-15 14:27:39 +00:00
[ this ] ( wxCommandEvent & ) { load_config_file ( ) ; } , " plugin_add.png " ) ;
2019-01-21 11:34:28 +00:00
append_menu_item ( import_menu , wxID_ANY , _ ( L ( " Import Config from &project " ) ) + dots + " \t Ctrl+Alt+L " , _ ( L ( " Load configuration from project file " ) ) ,
2018-11-16 08:26:41 +00:00
[ this ] ( wxCommandEvent & ) { if ( m_plater ) m_plater - > extract_config_from_project ( ) ; } , " plugin_add.png " ) ;
import_menu - > AppendSeparator ( ) ;
2019-01-21 11:34:28 +00:00
append_menu_item ( import_menu , wxID_ANY , _ ( L ( " Import Config &Bundle " ) ) + dots , _ ( L ( " Load presets from a bundle " ) ) ,
2018-11-15 14:27:39 +00:00
[ this ] ( wxCommandEvent & ) { load_configbundle ( ) ; } , " lorry_add.png " ) ;
2019-01-21 11:34:28 +00:00
append_submenu ( fileMenu , import_menu , wxID_ANY , _ ( L ( " &Import " ) ) , " " ) ;
2018-11-15 14:27:39 +00:00
wxMenu * export_menu = new wxMenu ( ) ;
2019-01-21 11:34:28 +00:00
wxMenuItem * item_export_gcode = append_menu_item ( export_menu , wxID_ANY , _ ( L ( " Export &G-code " ) ) + dots + " \t Ctrl+G " , _ ( L ( " Export current plate as G-code " ) ) ,
2018-11-15 14:27:39 +00:00
[ this ] ( wxCommandEvent & ) { if ( m_plater ) m_plater - > export_gcode ( ) ; } , " cog_go.png " ) ;
export_menu - > AppendSeparator ( ) ;
2019-01-21 11:34:28 +00:00
wxMenuItem * item_export_stl = append_menu_item ( export_menu , wxID_ANY , _ ( L ( " Export plate as &STL " ) ) + dots , _ ( L ( " Export current plate as STL " ) ) ,
2018-11-15 14:27:39 +00:00
[ this ] ( wxCommandEvent & ) { if ( m_plater ) m_plater - > export_stl ( ) ; } , " brick_go.png " ) ;
2019-01-21 11:34:28 +00:00
wxMenuItem * item_export_amf = append_menu_item ( export_menu , wxID_ANY , _ ( L ( " Export plate as &AMF " ) ) + dots , _ ( L ( " Export current plate as AMF " ) ) ,
2018-11-15 14:27:39 +00:00
[ this ] ( wxCommandEvent & ) { if ( m_plater ) m_plater - > export_amf ( ) ; } , " brick_go.png " ) ;
export_menu - > AppendSeparator ( ) ;
2019-01-21 11:34:28 +00:00
append_menu_item ( export_menu , wxID_ANY , _ ( L ( " Export &Config " ) ) + dots + " \t Ctrl+E " , _ ( L ( " Export current configuration to file " ) ) ,
2018-11-15 14:27:39 +00:00
[ this ] ( wxCommandEvent & ) { export_config ( ) ; } , " plugin_go.png " ) ;
2019-01-21 11:34:28 +00:00
append_menu_item ( export_menu , wxID_ANY , _ ( L ( " Export Config &Bundle " ) ) + dots , _ ( L ( " Export all presets to file " ) ) ,
2018-11-15 14:27:39 +00:00
[ this ] ( wxCommandEvent & ) { export_configbundle ( ) ; } , " lorry_go.png " ) ;
2019-01-21 11:34:28 +00:00
append_submenu ( fileMenu , export_menu , wxID_ANY , _ ( L ( " &Export " ) ) , " " ) ;
2018-11-15 14:27:39 +00:00
fileMenu - > AppendSeparator ( ) ;
2018-12-06 13:47:53 +00:00
#if 0
2018-11-15 11:21:09 +00:00
m_menu_item_repeat = nullptr ;
2019-01-21 11:34:28 +00:00
append_menu_item ( fileMenu , wxID_ANY , _ ( L ( " Quick Slice " ) ) + dots + " \t Ctrl+U " , _ ( L ( " Slice a file into a G-code " ) ) ,
2018-11-15 11:21:09 +00:00
[ this ] ( wxCommandEvent & ) {
wxTheApp - > CallAfter ( [ this ] ( ) {
2018-09-20 06:40:22 +00:00
quick_slice ( ) ;
2018-11-15 11:21:09 +00:00
m_menu_item_repeat - > Enable ( is_last_input_file ( ) ) ;
} ) ; } , " cog_go.png " ) ;
2019-01-21 11:34:28 +00:00
append_menu_item ( fileMenu , wxID_ANY , _ ( L ( " Quick Slice and Save As " ) ) + dots + " \t Ctrl+Alt+U " , _ ( L ( " Slice a file into a G-code, save as " ) ) ,
2018-11-15 11:21:09 +00:00
[ this ] ( wxCommandEvent & ) {
wxTheApp - > CallAfter ( [ this ] ( ) {
2018-09-20 23:33:41 +00:00
quick_slice ( qsSaveAs ) ;
2018-11-15 11:21:09 +00:00
m_menu_item_repeat - > Enable ( is_last_input_file ( ) ) ;
} ) ; } , " cog_go.png " ) ;
2019-01-21 11:34:28 +00:00
m_menu_item_repeat = append_menu_item ( fileMenu , wxID_ANY , _ ( L ( " Repeat Last Quick Slice " ) ) + " \t Ctrl+Shift+U " , _ ( L ( " Repeat last quick slice " ) ) ,
2018-10-31 11:56:08 +00:00
[ this ] ( wxCommandEvent & ) {
wxTheApp - > CallAfter ( [ this ] ( ) {
2018-09-20 23:33:41 +00:00
quick_slice ( qsReslice ) ;
2018-09-20 06:40:22 +00:00
} ) ; } , " cog_go.png " ) ;
2018-11-15 11:21:09 +00:00
m_menu_item_repeat - > Enable ( false ) ;
2018-09-20 06:40:22 +00:00
fileMenu - > AppendSeparator ( ) ;
2018-12-06 13:47:53 +00:00
# endif
2019-01-21 11:34:28 +00:00
m_menu_item_reslice_now = append_menu_item ( fileMenu , wxID_ANY , _ ( L ( " (Re)Slice &Now " ) ) + " \t Ctrl+R " , _ ( L ( " Start new slicing process " ) ) ,
2018-10-31 11:56:08 +00:00
[ this ] ( wxCommandEvent & ) { reslice_now ( ) ; } , " shape_handles.png " ) ;
2018-09-20 06:40:22 +00:00
fileMenu - > AppendSeparator ( ) ;
2019-01-21 11:34:28 +00:00
append_menu_item ( fileMenu , wxID_ANY , _ ( L ( " &Repair STL file " ) ) + dots , _ ( L ( " Automatically repair an STL file " ) ) ,
2018-10-31 11:56:08 +00:00
[ this ] ( wxCommandEvent & ) { repair_stl ( ) ; } , " wrench.png " ) ;
2018-09-20 06:40:22 +00:00
fileMenu - > AppendSeparator ( ) ;
2019-01-21 11:34:28 +00:00
append_menu_item ( fileMenu , wxID_EXIT , _ ( L ( " &Quit " ) ) , _ ( L ( " Quit Slic3r " ) ) ,
2018-11-21 09:21:12 +00:00
[ this ] ( wxCommandEvent & ) { Close ( false ) ; } ) ;
2018-11-15 14:27:39 +00:00
2018-11-16 08:26:41 +00:00
Bind ( wxEVT_UPDATE_UI , [ this ] ( wxUpdateUIEvent & evt ) { evt . Enable ( m_plater ! = nullptr ) ; } , item_open - > GetId ( ) ) ;
Bind ( wxEVT_UPDATE_UI , [ this ] ( wxUpdateUIEvent & evt ) { evt . Enable ( ( m_plater ! = nullptr ) & & can_save ( ) ) ; } , item_save - > GetId ( ) ) ;
Bind ( wxEVT_UPDATE_UI , [ this ] ( wxUpdateUIEvent & evt ) { evt . Enable ( ( m_plater ! = nullptr ) & & can_save ( ) ) ; } , item_save_as - > GetId ( ) ) ;
Bind ( wxEVT_UPDATE_UI , [ this ] ( wxUpdateUIEvent & evt ) { evt . Enable ( m_plater ! = nullptr ) ; } , item_import_model - > GetId ( ) ) ;
Bind ( wxEVT_UPDATE_UI , [ this ] ( wxUpdateUIEvent & evt ) { evt . Enable ( ( m_plater ! = nullptr ) & & can_export_gcode ( ) ) ; } , item_export_gcode - > GetId ( ) ) ;
Bind ( wxEVT_UPDATE_UI , [ this ] ( wxUpdateUIEvent & evt ) { evt . Enable ( ( m_plater ! = nullptr ) & & can_export_model ( ) ) ; } , item_export_stl - > GetId ( ) ) ;
Bind ( wxEVT_UPDATE_UI , [ this ] ( wxUpdateUIEvent & evt ) { evt . Enable ( ( m_plater ! = nullptr ) & & can_export_model ( ) ) ; } , item_export_amf - > GetId ( ) ) ;
2019-01-21 11:34:28 +00:00
Bind ( wxEVT_UPDATE_UI , [ this ] ( wxUpdateUIEvent & evt ) { evt . Enable ( ( m_plater ! = nullptr ) & & can_slice ( ) ) ; } , m_menu_item_reslice_now - > GetId ( ) ) ;
2018-09-20 06:40:22 +00:00
}
2019-02-04 11:04:42 +00:00
# ifdef _MSC_VER
// \xA0 is a non-breaking space. It is entered here to spoil the automatic accelerators,
// as the simple numeric accelerators spoil all numeric data entry.
wxString sep = " \t \xA0 " ;
wxString sep_space = " \xA0 " ;
# else
wxString sep = " - " ;
2019-02-04 11:08:48 +00:00
wxString sep_space = " " ;
2019-02-04 11:04:42 +00:00
# endif
2018-11-21 14:28:35 +00:00
// Edit menu
wxMenu * editMenu = nullptr ;
if ( m_plater ! = nullptr )
{
editMenu = new wxMenu ( ) ;
2019-02-04 14:46:12 +00:00
# ifdef __APPLE__
// Backspace sign
wxString hotkey_delete = " \u232b " ;
# else
wxString hotkey_delete = " Del " ;
# endif
wxMenuItem * item_select_all = append_menu_item ( editMenu , wxID_ANY , _ ( L ( " &Select all " ) ) + sep + GUI : : shortkey_ctrl_prefix ( ) + sep_space + " A " , _ ( L ( " Selects all objects " ) ) ,
2018-11-21 14:28:35 +00:00
[ this ] ( wxCommandEvent & ) { m_plater - > select_all ( ) ; } , " " ) ;
2018-11-22 10:31:53 +00:00
editMenu - > AppendSeparator ( ) ;
2019-02-04 14:46:12 +00:00
wxMenuItem * item_delete_sel = append_menu_item ( editMenu , wxID_ANY , _ ( L ( " &Delete selected " ) ) + sep + hotkey_delete , _ ( L ( " Deletes the current selection " ) ) ,
2018-11-21 14:47:41 +00:00
[ this ] ( wxCommandEvent & ) { m_plater - > remove_selected ( ) ; } , " " ) ;
2019-02-04 14:46:12 +00:00
wxMenuItem * item_delete_all = append_menu_item ( editMenu , wxID_ANY , _ ( L ( " Delete &all " ) ) + sep + GUI : : shortkey_ctrl_prefix ( ) + sep_space + hotkey_delete , _ ( L ( " Deletes all objects " ) ) ,
2018-11-22 10:31:53 +00:00
[ this ] ( wxCommandEvent & ) { m_plater - > reset ( ) ; } , " " ) ;
2018-11-21 14:28:35 +00:00
Bind ( wxEVT_UPDATE_UI , [ this ] ( wxUpdateUIEvent & evt ) { evt . Enable ( can_select ( ) ) ; } , item_select_all - > GetId ( ) ) ;
2018-11-21 14:47:41 +00:00
Bind ( wxEVT_UPDATE_UI , [ this ] ( wxUpdateUIEvent & evt ) { evt . Enable ( can_delete ( ) ) ; } , item_delete_sel - > GetId ( ) ) ;
2018-11-22 10:31:53 +00:00
Bind ( wxEVT_UPDATE_UI , [ this ] ( wxUpdateUIEvent & evt ) { evt . Enable ( can_delete_all ( ) ) ; } , item_delete_all - > GetId ( ) ) ;
2018-11-21 14:28:35 +00:00
}
2018-09-20 06:40:22 +00:00
// Window menu
auto windowMenu = new wxMenu ( ) ;
{
size_t tab_offset = 0 ;
if ( m_plater ) {
2019-01-21 11:34:28 +00:00
append_menu_item ( windowMenu , wxID_HIGHEST + 1 , _ ( L ( " &Plater Tab " ) ) + " \t Ctrl+1 " , _ ( L ( " Show the plater " ) ) ,
2018-12-04 12:55:25 +00:00
[ this ] ( wxCommandEvent & ) { select_tab ( 0 ) ; } , " application_view_tile.png " ) ;
2018-09-20 06:40:22 +00:00
tab_offset + = 1 ;
}
if ( tab_offset > 0 ) {
windowMenu - > AppendSeparator ( ) ;
}
2019-01-21 11:34:28 +00:00
append_menu_item ( windowMenu , wxID_HIGHEST + 2 , _ ( L ( " P&rint Settings Tab " ) ) + " \t Ctrl+2 " , _ ( L ( " Show the print settings " ) ) ,
2018-12-04 12:55:25 +00:00
[ this , tab_offset ] ( wxCommandEvent & ) { select_tab ( tab_offset + 0 ) ; } , " cog.png " ) ;
2019-01-21 11:34:28 +00:00
append_menu_item ( windowMenu , wxID_HIGHEST + 3 , _ ( L ( " &Filament Settings Tab " ) ) + " \t Ctrl+3 " , _ ( L ( " Show the filament settings " ) ) ,
2018-12-04 12:55:25 +00:00
[ this , tab_offset ] ( wxCommandEvent & ) { select_tab ( tab_offset + 1 ) ; } , " spool.png " ) ;
2019-01-21 11:34:28 +00:00
append_menu_item ( windowMenu , wxID_HIGHEST + 4 , _ ( L ( " Print&er Settings Tab " ) ) + " \t Ctrl+4 " , _ ( L ( " Show the printer settings " ) ) ,
2018-12-04 12:55:25 +00:00
[ this , tab_offset ] ( wxCommandEvent & ) { select_tab ( tab_offset + 2 ) ; } , " printer_empty.png " ) ;
if ( m_plater ) {
windowMenu - > AppendSeparator ( ) ;
2019-01-21 11:34:28 +00:00
wxMenuItem * item_3d = append_menu_item ( windowMenu , wxID_HIGHEST + 5 , _ ( L ( " 3&D " ) ) + " \t Ctrl+5 " , _ ( L ( " Show the 3D editing view " ) ) ,
2018-12-17 13:40:54 +00:00
[ this ] ( wxCommandEvent & ) { m_plater - > select_view_3D ( " 3D " ) ; } , " " ) ;
2019-01-21 11:34:28 +00:00
wxMenuItem * item_preview = append_menu_item ( windowMenu , wxID_HIGHEST + 6 , _ ( L ( " Pre&view " ) ) + " \t Ctrl+6 " , _ ( L ( " Show the 3D slices preview " ) ) ,
2018-12-17 13:40:54 +00:00
[ this ] ( wxCommandEvent & ) { m_plater - > select_view_3D ( " Preview " ) ; } , " " ) ;
2018-12-04 12:55:25 +00:00
Bind ( wxEVT_UPDATE_UI , [ this ] ( wxUpdateUIEvent & evt ) { evt . Enable ( can_change_view ( ) ) ; } , item_3d - > GetId ( ) ) ;
Bind ( wxEVT_UPDATE_UI , [ this ] ( wxUpdateUIEvent & evt ) { evt . Enable ( can_change_view ( ) ) ; } , item_preview - > GetId ( ) ) ;
}
2018-12-17 13:40:54 +00:00
# if _WIN32
// This is needed on Windows to fake the CTRL+# of the window menu when using the numpad
wxAcceleratorEntry entries [ 6 ] ;
entries [ 0 ] . Set ( wxACCEL_CTRL , WXK_NUMPAD1 , wxID_HIGHEST + 1 ) ;
entries [ 1 ] . Set ( wxACCEL_CTRL , WXK_NUMPAD2 , wxID_HIGHEST + 2 ) ;
entries [ 2 ] . Set ( wxACCEL_CTRL , WXK_NUMPAD3 , wxID_HIGHEST + 3 ) ;
entries [ 3 ] . Set ( wxACCEL_CTRL , WXK_NUMPAD4 , wxID_HIGHEST + 4 ) ;
entries [ 4 ] . Set ( wxACCEL_CTRL , WXK_NUMPAD5 , wxID_HIGHEST + 5 ) ;
entries [ 5 ] . Set ( wxACCEL_CTRL , WXK_NUMPAD6 , wxID_HIGHEST + 6 ) ;
wxAcceleratorTable accel ( 6 , entries ) ;
SetAcceleratorTable ( accel ) ;
# endif // _WIN32
2018-12-14 14:27:34 +00:00
windowMenu - > AppendSeparator ( ) ;
2019-01-21 11:34:28 +00:00
append_menu_item ( windowMenu , wxID_ANY , _ ( L ( " Print &Host Upload Queue " ) ) + " \t Ctrl+J " , _ ( L ( " Display the Print Host Upload Queue window " ) ) ,
2018-12-20 15:42:46 +00:00
[ this ] ( wxCommandEvent & ) { m_printhost_queue_dlg - > Show ( ) ; } , " arrow_up.png " ) ;
2018-09-20 06:40:22 +00:00
}
// View menu
2018-11-15 14:27:39 +00:00
wxMenu * viewMenu = nullptr ;
if ( m_plater ) {
viewMenu = new wxMenu ( ) ;
// The camera control accelerators are captured by GLCanvas3D::on_char().
2019-02-03 18:10:20 +00:00
wxMenuItem * item_iso = append_menu_item ( viewMenu , wxID_ANY , _ ( L ( " Iso " ) ) + sep + " &0 " , _ ( L ( " Iso View " ) ) , [ this ] ( wxCommandEvent & ) { select_view ( " iso " ) ; } ) ;
2018-11-15 14:27:39 +00:00
viewMenu - > AppendSeparator ( ) ;
2019-02-03 18:10:20 +00:00
wxMenuItem * item_top = append_menu_item ( viewMenu , wxID_ANY , _ ( L ( " Top " ) ) + sep + " &1 " , _ ( L ( " Top View " ) ) , [ this ] ( wxCommandEvent & ) { select_view ( " top " ) ; } ) ;
wxMenuItem * item_bottom = append_menu_item ( viewMenu , wxID_ANY , _ ( L ( " Bottom " ) ) + sep + " &2 " , _ ( L ( " Bottom View " ) ) , [ this ] ( wxCommandEvent & ) { select_view ( " bottom " ) ; } ) ;
wxMenuItem * item_front = append_menu_item ( viewMenu , wxID_ANY , _ ( L ( " Front " ) ) + sep + " &3 " , _ ( L ( " Front View " ) ) , [ this ] ( wxCommandEvent & ) { select_view ( " front " ) ; } ) ;
wxMenuItem * item_rear = append_menu_item ( viewMenu , wxID_ANY , _ ( L ( " Rear " ) ) + sep + " &4 " , _ ( L ( " Rear View " ) ) , [ this ] ( wxCommandEvent & ) { select_view ( " rear " ) ; } ) ;
wxMenuItem * item_left = append_menu_item ( viewMenu , wxID_ANY , _ ( L ( " Left " ) ) + sep + " &5 " , _ ( L ( " Left View " ) ) , [ this ] ( wxCommandEvent & ) { select_view ( " left " ) ; } ) ;
wxMenuItem * item_right = append_menu_item ( viewMenu , wxID_ANY , _ ( L ( " Right " ) ) + sep + " &6 " , _ ( L ( " Right View " ) ) , [ this ] ( wxCommandEvent & ) { select_view ( " right " ) ; } ) ;
2018-11-16 11:31:06 +00:00
Bind ( wxEVT_UPDATE_UI , [ this ] ( wxUpdateUIEvent & evt ) { evt . Enable ( can_change_view ( ) ) ; } , item_iso - > GetId ( ) ) ;
Bind ( wxEVT_UPDATE_UI , [ this ] ( wxUpdateUIEvent & evt ) { evt . Enable ( can_change_view ( ) ) ; } , item_top - > GetId ( ) ) ;
Bind ( wxEVT_UPDATE_UI , [ this ] ( wxUpdateUIEvent & evt ) { evt . Enable ( can_change_view ( ) ) ; } , item_bottom - > GetId ( ) ) ;
Bind ( wxEVT_UPDATE_UI , [ this ] ( wxUpdateUIEvent & evt ) { evt . Enable ( can_change_view ( ) ) ; } , item_front - > GetId ( ) ) ;
Bind ( wxEVT_UPDATE_UI , [ this ] ( wxUpdateUIEvent & evt ) { evt . Enable ( can_change_view ( ) ) ; } , item_rear - > GetId ( ) ) ;
Bind ( wxEVT_UPDATE_UI , [ this ] ( wxUpdateUIEvent & evt ) { evt . Enable ( can_change_view ( ) ) ; } , item_left - > GetId ( ) ) ;
Bind ( wxEVT_UPDATE_UI , [ this ] ( wxUpdateUIEvent & evt ) { evt . Enable ( can_change_view ( ) ) ; } , item_right - > GetId ( ) ) ;
2018-11-15 14:27:39 +00:00
}
2018-09-20 06:40:22 +00:00
// Help menu
auto helpMenu = new wxMenu ( ) ;
{
2019-01-21 11:34:28 +00:00
append_menu_item ( helpMenu , wxID_ANY , _ ( L ( " Prusa 3D &Drivers " ) ) , _ ( L ( " Open the Prusa3D drivers download page in your browser " ) ) ,
2018-10-31 11:56:08 +00:00
[ this ] ( wxCommandEvent & ) { wxLaunchDefaultBrowser ( " http://www.prusa3d.com/drivers/ " ) ; } ) ;
2019-01-21 11:34:28 +00:00
append_menu_item ( helpMenu , wxID_ANY , _ ( L ( " Prusa Edition &Releases " ) ) , _ ( L ( " Open the Prusa Edition releases page in your browser " ) ) ,
2018-10-31 11:56:08 +00:00
[ this ] ( wxCommandEvent & ) { wxLaunchDefaultBrowser ( " http://github.com/prusa3d/slic3r/releases " ) ; } ) ;
2018-09-20 06:40:22 +00:00
//# my $versioncheck = $self->_append_menu_item($helpMenu, "Check for &Updates...", "Check for new Slic3r versions", sub{
//# wxTheApp->check_version(1);
//# });
//# $versioncheck->Enable(wxTheApp->have_version_check);
2019-01-21 11:34:28 +00:00
append_menu_item ( helpMenu , wxID_ANY , _ ( L ( " Slic3r &Website " ) ) , _ ( L ( " Open the Slic3r website in your browser " ) ) ,
2018-10-31 11:56:08 +00:00
[ this ] ( wxCommandEvent & ) { wxLaunchDefaultBrowser ( " http://slic3r.org/ " ) ; } ) ;
2019-01-21 11:34:28 +00:00
append_menu_item ( helpMenu , wxID_ANY , _ ( L ( " Slic3r &Manual " ) ) , _ ( L ( " Open the Slic3r manual in your browser " ) ) ,
2018-10-31 11:56:08 +00:00
[ this ] ( wxCommandEvent & ) { wxLaunchDefaultBrowser ( " http://manual.slic3r.org/ " ) ; } ) ;
2018-09-20 06:40:22 +00:00
helpMenu - > AppendSeparator ( ) ;
2019-01-21 11:34:28 +00:00
append_menu_item ( helpMenu , wxID_ANY , _ ( L ( " System &Info " ) ) , _ ( L ( " Show system information " ) ) ,
2018-10-31 11:56:08 +00:00
[ this ] ( wxCommandEvent & ) { wxGetApp ( ) . system_info ( ) ; } ) ;
2019-01-21 11:34:28 +00:00
append_menu_item ( helpMenu , wxID_ANY , _ ( L ( " Show &Configuration Folder " ) ) , _ ( L ( " Show user configuration folder (datadir) " ) ) ,
2018-10-31 11:56:08 +00:00
[ this ] ( wxCommandEvent & ) { Slic3r : : GUI : : desktop_open_datadir_folder ( ) ; } ) ;
2019-01-21 11:34:28 +00:00
append_menu_item ( helpMenu , wxID_ANY , _ ( L ( " Report an I&ssue " ) ) , _ ( L ( " Report an issue on the Slic3r Prusa Edition " ) ) ,
2018-10-31 11:56:08 +00:00
[ this ] ( wxCommandEvent & ) { wxLaunchDefaultBrowser ( " http://github.com/prusa3d/slic3r/issues/new " ) ; } ) ;
2019-01-21 11:34:28 +00:00
append_menu_item ( helpMenu , wxID_ANY , _ ( L ( " &About Slic3r " ) ) , _ ( L ( " Show about dialog " ) ) ,
2018-10-31 11:56:08 +00:00
[ this ] ( wxCommandEvent & ) { Slic3r : : GUI : : about ( ) ; } ) ;
2018-12-19 12:06:24 +00:00
helpMenu - > AppendSeparator ( ) ;
2019-02-03 18:10:20 +00:00
append_menu_item ( helpMenu , wxID_ANY , _ ( L ( " Keyboard Shortcuts " ) ) + sep + " &? " , _ ( L ( " Show the list of the keyboard shortcuts " ) ) ,
2018-12-19 12:06:24 +00:00
[ this ] ( wxCommandEvent & ) { wxGetApp ( ) . keyboard_shortcuts ( ) ; } ) ;
2018-09-20 06:40:22 +00:00
}
// menubar
// assign menubar to frame after appending items, otherwise special items
// will not be handled correctly
2019-01-14 15:48:23 +00:00
auto menubar = new wxMenuBar ( ) ;
2019-01-21 11:34:28 +00:00
menubar - > Append ( fileMenu , _ ( L ( " &File " ) ) ) ;
if ( editMenu ) menubar - > Append ( editMenu , _ ( L ( " &Edit " ) ) ) ;
menubar - > Append ( windowMenu , _ ( L ( " &Window " ) ) ) ;
if ( viewMenu ) menubar - > Append ( viewMenu , _ ( L ( " &View " ) ) ) ;
2019-01-14 15:48:23 +00:00
// Add additional menus from C++
wxGetApp ( ) . add_config_menu ( menubar ) ;
2019-01-21 11:34:28 +00:00
menubar - > Append ( helpMenu , _ ( L ( " &Help " ) ) ) ;
2019-01-14 15:48:23 +00:00
SetMenuBar ( menubar ) ;
# ifdef __APPLE__
2019-01-11 17:09:21 +00:00
// This fixes a bug on Mac OS where the quit command doesn't emit window close events
// wx bug: https://trac.wxwidgets.org/ticket/18328
2019-01-14 15:48:23 +00:00
wxMenu * apple_menu = menubar - > OSXGetAppleMenu ( ) ;
if ( apple_menu ! = nullptr ) {
apple_menu - > Bind ( wxEVT_MENU , [ this ] ( wxCommandEvent & ) {
Close ( ) ;
} , wxID_EXIT ) ;
2018-09-20 06:40:22 +00:00
}
2019-01-14 15:48:23 +00:00
# endif
2018-09-20 06:40:22 +00:00
}
// To perform the "Quck Slice", "Quick Slice and Save As", "Repeat last Quick Slice" and "Slice to SVG".
2018-10-31 11:56:08 +00:00
void MainFrame : : quick_slice ( const int qs )
{
2018-09-20 06:40:22 +00:00
// my $progress_dialog;
wxString input_file ;
// eval
// {
// validate configuration
2018-09-20 23:33:41 +00:00
auto config = wxGetApp ( ) . preset_bundle - > full_config ( ) ;
2018-09-20 06:40:22 +00:00
config . validate ( ) ;
// select input file
2018-09-20 23:33:41 +00:00
if ( ! ( qs & qsReslice ) ) {
2018-09-20 06:40:22 +00:00
auto dlg = new wxFileDialog ( this , _ ( L ( " Choose a file to slice (STL/OBJ/AMF/3MF/PRUSA): " ) ) ,
2018-09-20 23:33:41 +00:00
wxGetApp ( ) . app_config - > get_last_dir ( ) , " " ,
2018-12-06 16:32:49 +00:00
file_wildcards ( FT_MODEL ) , wxFD_OPEN | wxFD_FILE_MUST_EXIST ) ;
2018-09-20 06:40:22 +00:00
if ( dlg - > ShowModal ( ) ! = wxID_OK ) {
dlg - > Destroy ( ) ;
return ;
}
input_file = dlg - > GetPath ( ) ;
dlg - > Destroy ( ) ;
2018-09-20 23:33:41 +00:00
if ( ! ( qs & qsExportSVG ) )
2018-09-20 06:40:22 +00:00
m_qs_last_input_file = input_file ;
}
else {
if ( m_qs_last_input_file . IsEmpty ( ) ) {
auto dlg = new wxMessageDialog ( this , _ ( L ( " No previously sliced file. " ) ) ,
_ ( L ( " Error " ) ) , wxICON_ERROR | wxOK ) ;
dlg - > ShowModal ( ) ;
return ;
}
if ( std : : ifstream ( m_qs_last_input_file . char_str ( ) ) ) {
auto dlg = new wxMessageDialog ( this , _ ( L ( " Previously sliced file ( " ) ) + m_qs_last_input_file + _ ( L ( " ) not found. " ) ) ,
_ ( L ( " File Not Found " ) ) , wxICON_ERROR | wxOK ) ;
dlg - > ShowModal ( ) ;
return ;
}
input_file = m_qs_last_input_file ;
}
auto input_file_basename = get_base_name ( input_file ) ;
2018-09-20 23:33:41 +00:00
wxGetApp ( ) . app_config - > update_skein_dir ( get_dir_name ( input_file ) ) ;
2018-09-20 06:40:22 +00:00
auto bed_shape = Slic3r : : Polygon : : new_scale ( config . option < ConfigOptionPoints > ( " bed_shape " ) - > values ) ;
// auto print_center = Slic3r::Pointf->new_unscale(bed_shape.bounding_box().center());
//
// auto sprint = new Slic3r::Print::Simple(
// print_center = > print_center,
2018-10-31 11:56:08 +00:00
// status_cb = > [](int percent, const wxString& msg) {
2018-09-20 23:33:41 +00:00
// m_progress_dialog->Update(percent, msg+"…");
2018-09-20 06:40:22 +00:00
// });
// keep model around
2019-01-03 13:34:53 +00:00
auto model = Slic3r : : Model : : read_from_file ( input_file . ToUTF8 ( ) . data ( ) ) ;
2018-09-20 06:40:22 +00:00
// sprint->apply_config(config);
// sprint->set_model(model);
// Copy the names of active presets into the placeholder parser.
2018-09-20 23:33:41 +00:00
// wxGetApp().preset_bundle->export_selections(sprint->placeholder_parser);
2018-09-20 06:40:22 +00:00
// select output file
wxString output_file ;
2018-09-20 23:33:41 +00:00
if ( qs & qsReslice ) {
2018-09-20 06:40:22 +00:00
if ( ! m_qs_last_output_file . IsEmpty ( ) )
output_file = m_qs_last_output_file ;
}
2018-09-20 23:33:41 +00:00
else if ( qs & qsSaveAs ) {
2018-09-20 06:40:22 +00:00
// The following line may die if the output_filename_format template substitution fails.
// output_file = sprint->output_filepath;
// if (export_svg)
// output_file = ~s / \.[gG][cC][oO][dD][eE]$ / .svg /;
2018-09-20 23:33:41 +00:00
auto dlg = new wxFileDialog ( this , _ ( L ( " Save " ) ) + ( qs & qsExportSVG ? _ ( L ( " SVG " ) ) : _ ( L ( " G-code " ) ) ) + _ ( L ( " file as: " ) ) ,
wxGetApp ( ) . app_config - > get_last_output_dir ( get_dir_name ( output_file ) ) , get_base_name ( input_file ) ,
2018-12-06 16:32:49 +00:00
qs & qsExportSVG ? file_wildcards ( FT_SVG ) : file_wildcards ( FT_GCODE ) ,
2018-09-20 06:40:22 +00:00
wxFD_SAVE | wxFD_OVERWRITE_PROMPT ) ;
if ( dlg - > ShowModal ( ) ! = wxID_OK ) {
dlg - > Destroy ( ) ;
return ;
}
output_file = dlg - > GetPath ( ) ;
dlg - > Destroy ( ) ;
2018-09-20 23:33:41 +00:00
if ( ! ( qs & qsExportSVG ) )
2018-09-20 06:40:22 +00:00
m_qs_last_output_file = output_file ;
2018-09-20 23:33:41 +00:00
wxGetApp ( ) . app_config - > update_last_output_dir ( get_dir_name ( output_file ) ) ;
2018-09-20 06:40:22 +00:00
}
2018-09-20 23:33:41 +00:00
else if ( qs & qsExportPNG ) {
2018-09-20 06:40:22 +00:00
// output_file = sprint->output_filepath;
// output_file = ~s / \.[gG][cC][oO][dD][eE]$ / .zip / ;
auto dlg = new wxFileDialog ( this , _ ( L ( " Save zip file as: " ) ) ,
2018-09-20 23:33:41 +00:00
wxGetApp ( ) . app_config - > get_last_output_dir ( get_dir_name ( output_file ) ) ,
2018-09-20 06:40:22 +00:00
get_base_name ( output_file ) , " *.zip " , wxFD_SAVE | wxFD_OVERWRITE_PROMPT ) ;
if ( dlg - > ShowModal ( ) ! = wxID_OK ) {
dlg - > Destroy ( ) ;
return ;
}
output_file = dlg - > GetPath ( ) ;
dlg - > Destroy ( ) ;
}
// show processbar dialog
2019-01-21 11:34:28 +00:00
m_progress_dialog = new wxProgressDialog ( _ ( L ( " Slicing " ) ) + dots , _ ( L ( " Processing " ) ) + input_file_basename + " … " ,
2018-09-20 06:40:22 +00:00
100 , this , 4 ) ;
m_progress_dialog - > Pulse ( ) ;
{
// my @warnings = ();
// local $SIG{ __WARN__ } = sub{ push @warnings, $_[0] };
// sprint->output_file(output_file);
// if (export_svg) {
// sprint->export_svg();
// }
// else if(export_png) {
// sprint->export_png();
// }
// else {
// sprint->export_gcode();
// }
// sprint->status_cb(undef);
// Slic3r::GUI::warning_catcher($self)->($_) for @warnings;
}
m_progress_dialog - > Destroy ( ) ;
m_progress_dialog = nullptr ;
auto message = input_file_basename + _ ( L ( " was successfully sliced. " ) ) ;
// wxTheApp->notify(message);
wxMessageDialog ( this , message , _ ( L ( " Slicing Done! " ) ) , wxOK | wxICON_INFORMATION ) . ShowModal ( ) ;
// };
2018-10-31 11:56:08 +00:00
// Slic3r::GUI::catch_error(this, []() { if (m_progress_dialog) m_progress_dialog->Destroy(); });
2018-09-20 06:40:22 +00:00
}
2018-10-17 09:12:38 +00:00
void MainFrame : : reslice_now ( )
{
if ( m_plater )
m_plater - > reslice ( ) ;
2018-09-20 06:40:22 +00:00
}
void MainFrame : : repair_stl ( )
{
wxString input_file ;
{
auto dlg = new wxFileDialog ( this , _ ( L ( " Select the STL file to repair: " ) ) ,
2018-09-20 23:33:41 +00:00
wxGetApp ( ) . app_config - > get_last_dir ( ) , " " ,
2018-12-06 16:32:49 +00:00
file_wildcards ( FT_STL ) , wxFD_OPEN | wxFD_FILE_MUST_EXIST ) ;
2018-09-20 06:40:22 +00:00
if ( dlg - > ShowModal ( ) ! = wxID_OK ) {
dlg - > Destroy ( ) ;
return ;
}
input_file = dlg - > GetPath ( ) ;
dlg - > Destroy ( ) ;
}
auto output_file = input_file ;
{
// output_file = ~s / \.[sS][tT][lL]$ / _fixed.obj / ;
auto dlg = new wxFileDialog ( this , L ( " Save OBJ file (less prone to coordinate errors than STL) as: " ) ,
get_dir_name ( output_file ) , get_base_name ( output_file ) ,
2018-12-06 16:32:49 +00:00
file_wildcards ( FT_OBJ ) , wxFD_SAVE | wxFD_OVERWRITE_PROMPT ) ;
2018-09-20 06:40:22 +00:00
if ( dlg - > ShowModal ( ) ! = wxID_OK ) {
dlg - > Destroy ( ) ;
return /*undef*/ ;
}
output_file = dlg - > GetPath ( ) ;
dlg - > Destroy ( ) ;
}
auto tmesh = new Slic3r : : TriangleMesh ( ) ;
tmesh - > ReadSTLFile ( input_file . char_str ( ) ) ;
tmesh - > repair ( ) ;
tmesh - > WriteOBJFile ( output_file . char_str ( ) ) ;
Slic3r : : GUI : : show_info ( this , L ( " Your file was repaired. " ) , L ( " Repair " ) ) ;
}
void MainFrame : : export_config ( )
{
// Generate a cummulative configuration for the selected print, filaments and printer.
2018-09-20 23:33:41 +00:00
auto config = wxGetApp ( ) . preset_bundle - > full_config ( ) ;
2018-09-20 06:40:22 +00:00
// Validate the cummulative configuration.
auto valid = config . validate ( ) ;
if ( ! valid . empty ( ) ) {
// Slic3r::GUI::catch_error(this);
return ;
}
// Ask user for the file name for the config file.
auto dlg = new wxFileDialog ( this , _ ( L ( " Save configuration as: " ) ) ,
2018-09-20 23:33:41 +00:00
! m_last_config . IsEmpty ( ) ? get_dir_name ( m_last_config ) : wxGetApp ( ) . app_config - > get_last_dir ( ) ,
2018-09-20 06:40:22 +00:00
! m_last_config . IsEmpty ( ) ? get_base_name ( m_last_config ) : " config.ini " ,
2018-12-06 16:32:49 +00:00
file_wildcards ( FT_INI ) , wxFD_SAVE | wxFD_OVERWRITE_PROMPT ) ;
2018-09-21 13:42:31 +00:00
wxString file ;
if ( dlg - > ShowModal ( ) = = wxID_OK )
file = dlg - > GetPath ( ) ;
2018-09-20 06:40:22 +00:00
dlg - > Destroy ( ) ;
if ( ! file . IsEmpty ( ) ) {
2018-09-20 23:33:41 +00:00
wxGetApp ( ) . app_config - > update_config_dir ( get_dir_name ( file ) ) ;
2018-09-20 06:40:22 +00:00
m_last_config = file ;
2019-01-03 13:34:53 +00:00
config . save ( file . ToUTF8 ( ) . data ( ) ) ;
2018-09-20 06:40:22 +00:00
}
}
// Load a config file containing a Print, Filament & Printer preset.
2019-01-09 09:43:17 +00:00
void MainFrame : : load_config_file ( )
2018-09-20 06:40:22 +00:00
{
2019-01-09 09:43:17 +00:00
if ( ! wxGetApp ( ) . check_unsaved_changes ( ) )
return ;
auto dlg = new wxFileDialog ( this , _ ( L ( " Select configuration to load: " ) ) ,
! m_last_config . IsEmpty ( ) ? get_dir_name ( m_last_config ) : wxGetApp ( ) . app_config - > get_last_dir ( ) ,
" config.ini " , " INI files (*.ini, *.gcode)|*.ini;*.INI;*.gcode;*.g " , wxFD_OPEN | wxFD_FILE_MUST_EXIST ) ;
wxString file ;
if ( dlg - > ShowModal ( ) = = wxID_OK )
file = dlg - > GetPath ( ) ;
dlg - > Destroy ( ) ;
if ( ! file . IsEmpty ( ) & & this - > load_config_file ( file . ToUTF8 ( ) . data ( ) ) ) {
wxGetApp ( ) . app_config - > update_config_dir ( get_dir_name ( file ) ) ;
m_last_config = file ;
2018-09-20 06:40:22 +00:00
}
2019-01-09 09:43:17 +00:00
}
// Load a config file containing a Print, Filament & Printer preset from command line.
bool MainFrame : : load_config_file ( const std : : string & path )
{
2018-10-17 09:12:38 +00:00
try {
2019-01-09 09:43:17 +00:00
wxGetApp ( ) . preset_bundle - > load_config_file ( path ) ;
2018-12-03 12:14:28 +00:00
} catch ( const std : : exception & ex ) {
show_error ( this , ex . what ( ) ) ;
2019-01-09 09:43:17 +00:00
return false ;
2018-10-17 09:12:38 +00:00
}
2019-01-09 09:43:17 +00:00
wxGetApp ( ) . load_current_presets ( ) ;
return true ;
2018-09-20 06:40:22 +00:00
}
void MainFrame : : export_configbundle ( )
{
2018-09-20 23:33:41 +00:00
if ( ! wxGetApp ( ) . check_unsaved_changes ( ) )
2018-09-20 06:40:22 +00:00
return ;
// validate current configuration in case it's dirty
2018-12-03 12:14:28 +00:00
auto err = wxGetApp ( ) . preset_bundle - > full_config ( ) . validate ( ) ;
if ( ! err . empty ( ) ) {
show_error ( this , err ) ;
2018-09-20 06:40:22 +00:00
return ;
}
// Ask user for a file name.
auto dlg = new wxFileDialog ( this , _ ( L ( " Save presets bundle as: " ) ) ,
2018-09-20 23:33:41 +00:00
! m_last_config . IsEmpty ( ) ? get_dir_name ( m_last_config ) : wxGetApp ( ) . app_config - > get_last_dir ( ) ,
2018-09-20 06:40:22 +00:00
" Slic3r_config_bundle.ini " ,
2018-12-06 16:32:49 +00:00
file_wildcards ( FT_INI ) , wxFD_SAVE | wxFD_OVERWRITE_PROMPT ) ;
2018-09-21 13:42:31 +00:00
wxString file ;
if ( dlg - > ShowModal ( ) = = wxID_OK )
file = dlg - > GetPath ( ) ;
2018-09-20 06:40:22 +00:00
dlg - > Destroy ( ) ;
if ( ! file . IsEmpty ( ) ) {
// Export the config bundle.
2018-10-17 09:12:38 +00:00
wxGetApp ( ) . app_config - > update_config_dir ( get_dir_name ( file ) ) ;
try {
2019-01-03 13:34:53 +00:00
wxGetApp ( ) . preset_bundle - > export_configbundle ( file . ToUTF8 ( ) . data ( ) ) ;
2018-12-03 12:14:28 +00:00
} catch ( const std : : exception & ex ) {
show_error ( this , ex . what ( ) ) ;
2018-10-17 09:12:38 +00:00
}
2018-09-20 06:40:22 +00:00
}
}
// Loading a config bundle with an external file name used to be used
// to auto - install a config bundle on a fresh user account,
// but that behavior was not documented and likely buggy.
2018-10-17 09:12:38 +00:00
void MainFrame : : load_configbundle ( wxString file /* = wxEmptyString, const bool reset_user_profile*/ )
{
2018-09-20 23:33:41 +00:00
if ( ! wxGetApp ( ) . check_unsaved_changes ( ) )
2018-09-20 06:40:22 +00:00
return ;
if ( file . IsEmpty ( ) ) {
auto dlg = new wxFileDialog ( this , _ ( L ( " Select configuration to load: " ) ) ,
2018-09-20 23:33:41 +00:00
! m_last_config . IsEmpty ( ) ? get_dir_name ( m_last_config ) : wxGetApp ( ) . app_config - > get_last_dir ( ) ,
2018-12-06 16:32:49 +00:00
" config.ini " , file_wildcards ( FT_INI ) , wxFD_OPEN | wxFD_FILE_MUST_EXIST ) ;
2019-01-09 09:43:17 +00:00
if ( dlg - > ShowModal ( ) ! = wxID_OK ) {
dlg - > Destroy ( ) ;
return ;
}
2018-09-20 06:40:22 +00:00
file = dlg - > GetPath ( ) ;
2019-01-09 09:43:17 +00:00
dlg - > Destroy ( ) ;
}
2018-09-20 06:40:22 +00:00
2018-09-20 23:33:41 +00:00
wxGetApp ( ) . app_config - > update_config_dir ( get_dir_name ( file ) ) ;
2018-09-20 06:40:22 +00:00
auto presets_imported = 0 ;
2018-10-17 09:12:38 +00:00
try {
2019-01-03 13:34:53 +00:00
presets_imported = wxGetApp ( ) . preset_bundle - > load_configbundle ( file . ToUTF8 ( ) . data ( ) ) ;
2018-12-03 12:14:28 +00:00
} catch ( const std : : exception & ex ) {
show_error ( this , ex . what ( ) ) ;
return ;
2018-10-17 09:12:38 +00:00
}
2018-09-20 06:40:22 +00:00
// Load the currently selected preset into the GUI, update the preset selection box.
2018-11-07 13:57:50 +00:00
wxGetApp ( ) . load_current_presets ( ) ;
2018-09-20 06:40:22 +00:00
const auto message = wxString : : Format ( _ ( L ( " %d presets successfully imported. " ) ) , presets_imported ) ;
Slic3r : : GUI : : show_info ( this , message , " Info " ) ;
}
// Load a provied DynamicConfig into the Print / Filament / Printer tabs, thus modifying the active preset.
// Also update the platter with the new presets.
2018-10-17 09:12:38 +00:00
void MainFrame : : load_config ( const DynamicPrintConfig & config )
{
2019-01-09 09:43:17 +00:00
PrinterTechnology printer_technology = wxGetApp ( ) . preset_bundle - > printers . get_edited_preset ( ) . printer_technology ( ) ;
const auto * opt_printer_technology = config . option < ConfigOptionEnum < PrinterTechnology > > ( " printer_technology " ) ;
if ( opt_printer_technology ! = nullptr & & opt_printer_technology - > value ! = printer_technology ) {
printer_technology = opt_printer_technology - > value ;
this - > plater ( ) - > set_printer_technology ( printer_technology ) ;
}
#if 0
for ( auto tab : wxGetApp ( ) . tabs_list )
if ( tab - > supports_printer_technology ( printer_technology ) ) {
if ( tab - > name ( ) = = " printer " )
static_cast < TabPrinter * > ( tab ) - > update_pages ( ) ;
tab - > load_config ( config ) ;
}
if ( m_plater )
2018-10-17 09:12:38 +00:00
m_plater - > on_config_change ( config ) ;
2019-01-09 09:43:17 +00:00
# else
// Load the currently selected preset into the GUI, update the preset selection box.
//FIXME this is not quite safe for multi-extruder printers,
// as the number of extruders is not adjusted for the vector values.
// (see PresetBundle::update_multi_material_filament_presets())
// Better to call PresetBundle::load_config() instead?
for ( auto tab : wxGetApp ( ) . tabs_list )
if ( tab - > supports_printer_technology ( printer_technology ) ) {
// Only apply keys, which are present in the tab's config. Ignore the other keys.
for ( const std : : string & opt_key : tab - > get_config ( ) - > diff ( config ) )
// Ignore print_settings_id, printer_settings_id, filament_settings_id etc.
if ( ! boost : : algorithm : : ends_with ( opt_key , " _settings_id " ) )
tab - > get_config ( ) - > option ( opt_key ) - > set ( config . option ( opt_key ) ) ;
}
wxGetApp ( ) . load_current_presets ( ) ;
# endif
2018-09-20 06:40:22 +00:00
}
2018-10-17 09:12:38 +00:00
void MainFrame : : select_tab ( size_t tab ) const
{
2018-09-20 06:40:22 +00:00
m_tabpanel - > SetSelection ( tab ) ;
}
// Set a camera direction, zoom to all objects.
2018-10-17 09:12:38 +00:00
void MainFrame : : select_view ( const std : : string & direction )
{
2018-10-17 10:59:58 +00:00
if ( m_plater )
m_plater - > select_view ( direction ) ;
2018-09-20 06:40:22 +00:00
}
2018-10-03 14:27:02 +00:00
void MainFrame : : on_presets_changed ( SimpleEvent & event )
{
auto * tab = dynamic_cast < Tab * > ( event . GetEventObject ( ) ) ;
wxASSERT ( tab ! = nullptr ) ;
if ( tab = = nullptr ) {
return ;
}
// Update preset combo boxes(Print settings, Filament, Material, Printer) from their respective tabs.
auto presets = tab - > get_presets ( ) ;
2018-10-04 09:12:55 +00:00
if ( m_plater ! = nullptr & & presets ! = nullptr ) {
2018-10-03 14:27:02 +00:00
// FIXME: The preset type really should be a property of Tab instead
2018-10-09 10:41:05 +00:00
Slic3r : : Preset : : Type preset_type = tab - > type ( ) ;
2018-10-31 11:56:08 +00:00
if ( preset_type = = Slic3r : : Preset : : TYPE_INVALID ) {
2018-10-03 14:27:02 +00:00
wxASSERT ( false ) ;
return ;
}
2018-10-17 09:12:38 +00:00
m_plater - > on_config_change ( * tab - > get_config ( ) ) ;
2018-11-16 10:14:56 +00:00
m_plater - > sidebar ( ) . update_presets ( preset_type ) ;
2018-10-03 14:27:02 +00:00
}
}
2018-10-10 11:53:45 +00:00
void MainFrame : : on_value_changed ( wxCommandEvent & event )
2018-10-09 10:41:05 +00:00
{
2018-10-10 11:53:45 +00:00
auto * tab = dynamic_cast < Tab * > ( event . GetEventObject ( ) ) ;
wxASSERT ( tab ! = nullptr ) ;
if ( tab = = nullptr )
return ;
auto opt_key = event . GetString ( ) ;
if ( m_plater ) {
2018-10-17 09:12:38 +00:00
m_plater - > on_config_change ( * tab - > get_config ( ) ) ; // propagate config change events to the plater
2018-10-31 11:56:08 +00:00
if ( opt_key = = " extruders_count " ) {
2018-10-17 09:12:38 +00:00
auto value = event . GetInt ( ) ;
m_plater - > on_extruders_change ( value ) ;
}
}
// Don't save while loading for the first time.
if ( m_loaded ) {
AppConfig & cfg = * wxGetApp ( ) . app_config ;
if ( cfg . get ( " autosave " ) = = " 1 " )
cfg . save ( ) ;
2018-10-10 11:53:45 +00:00
}
2018-10-09 10:41:05 +00:00
}
2018-09-20 06:40:22 +00:00
// Called after the Preferences dialog is closed and the program settings are saved.
// Update the UI based on the current preferences.
void MainFrame : : update_ui_from_settings ( )
{
2018-12-04 11:30:47 +00:00
bool bp_on = wxGetApp ( ) . app_config - > get ( " background_processing " ) = = " 1 " ;
2019-01-21 11:34:28 +00:00
// m_menu_item_reslice_now->Enable(!bp_on);
2018-12-11 09:33:11 +00:00
m_plater - > sidebar ( ) . show_reslice ( ! bp_on ) ;
2018-12-10 09:38:32 +00:00
m_plater - > sidebar ( ) . Layout ( ) ;
2018-12-04 10:14:39 +00:00
if ( m_plater )
m_plater - > update_ui_from_settings ( ) ;
2018-11-16 10:14:56 +00:00
for ( auto tab : wxGetApp ( ) . tabs_list )
tab - > update_ui_from_settings ( ) ;
2018-09-20 06:40:22 +00:00
}
2019-01-09 09:43:17 +00:00
std : : string MainFrame : : get_base_name ( const wxString & full_name ) const
2018-09-20 06:40:22 +00:00
{
2019-01-09 09:43:17 +00:00
return boost : : filesystem : : path ( full_name . wx_str ( ) ) . filename ( ) . string ( ) ;
2018-09-20 06:40:22 +00:00
}
2019-01-09 09:43:17 +00:00
std : : string MainFrame : : get_dir_name ( const wxString & full_name ) const
2018-09-20 06:40:22 +00:00
{
2019-01-09 09:43:17 +00:00
return boost : : filesystem : : path ( full_name . wx_str ( ) ) . parent_path ( ) . string ( ) ;
2018-09-20 06:40:22 +00:00
}
} // GUI
2018-09-20 23:33:41 +00:00
} // Slic3r