GUI initialization extracted from PrusaSlicer.cpp to GUI_Init.cpp/hpp.
Implemented try/catch blocks for Slic3r exceptions and std::exceptions with GUI error reporting. This is extremely important to report corruption of PrusaSlicer.ini.
This commit is contained in:
parent
0f9faeda98
commit
027ab4fb02
@ -27,6 +27,7 @@ src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp
|
||||
src/slic3r/GUI/GUI.cpp
|
||||
src/slic3r/GUI/GUI_App.cpp
|
||||
src/slic3r/GUI/GUI_Init.cpp
|
||||
src/slic3r/GUI/GUI_ObjectLayers.cpp
|
||||
src/slic3r/GUI/GUI_ObjectList.cpp
|
||||
src/slic3r/GUI/GUI_ObjectManipulation.cpp
|
||||
|
@ -45,18 +45,12 @@
|
||||
#include "libslic3r/Format/OBJ.hpp"
|
||||
#include "libslic3r/Format/SL1.hpp"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "libslic3r/AppConfig.hpp"
|
||||
#include "libslic3r/Thread.hpp"
|
||||
|
||||
#include "PrusaSlicer.hpp"
|
||||
|
||||
#ifdef SLIC3R_GUI
|
||||
#include "slic3r/GUI/GUI.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/3DScene.hpp"
|
||||
#include "slic3r/GUI/InstanceCheck.hpp"
|
||||
#include "slic3r/GUI/MainFrame.hpp"
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "slic3r/GUI/GUI_Init.hpp"
|
||||
#endif /* SLIC3R_GUI */
|
||||
|
||||
using namespace Slic3r;
|
||||
@ -578,75 +572,20 @@ int CLI::run(int argc, char **argv)
|
||||
|
||||
if (start_gui) {
|
||||
#ifdef SLIC3R_GUI
|
||||
// #ifdef USE_WX
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
GUI::GUI_App* gui = new GUI::GUI_App(start_as_gcodeviewer ? GUI::GUI_App::EAppMode::GCodeViewer : GUI::GUI_App::EAppMode::Editor);
|
||||
if (gui->get_app_mode() != GUI::GUI_App::EAppMode::GCodeViewer) {
|
||||
// G-code viewer is currently not performing instance check, a new G-code viewer is started every time.
|
||||
bool gui_single_instance_setting = gui->app_config->get("single_instance") == "1";
|
||||
if (Slic3r::instance_check(argc, argv, gui_single_instance_setting)) {
|
||||
//TODO: do we have delete gui and other stuff?
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
GUI::GUI_App *gui = new GUI::GUI_App();
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
|
||||
// gui->autosave = m_config.opt_string("autosave");
|
||||
GUI::GUI_App::SetInstance(gui);
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
gui->after_init_loads.set_params(load_configs, m_extra_config, m_input_files, start_as_gcodeviewer);
|
||||
#else
|
||||
gui->after_init_loads.set_params(load_configs, m_extra_config, m_input_files);
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
/*
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
gui->CallAfter([gui, this, &load_configs, start_as_gcodeviewer] {
|
||||
#else
|
||||
gui->CallAfter([gui, this, &load_configs] {
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
if (!gui->initialized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
if (start_as_gcodeviewer) {
|
||||
if (!m_input_files.empty())
|
||||
gui->plater()->load_gcode(wxString::FromUTF8(m_input_files[0].c_str()));
|
||||
} else {
|
||||
#endif // ENABLE_GCODE_VIEWER_AS
|
||||
#if 0
|
||||
// Load the cummulative config over the currently active profiles.
|
||||
//FIXME if multiple configs are loaded, only the last one will have an effect.
|
||||
// We need to decide what to do about loading of separate presets (just print preset, just filament preset etc).
|
||||
// As of now only the full configs are supported here.
|
||||
if (!m_print_config.empty())
|
||||
gui->mainframe->load_config(m_print_config);
|
||||
#endif
|
||||
if (!load_configs.empty())
|
||||
// Load the last config to give it a name at the UI. The name of the preset may be later
|
||||
// changed by loading an AMF or 3MF.
|
||||
//FIXME this is not strictly correct, as one may pass a print/filament/printer profile here instead of a full config.
|
||||
gui->mainframe->load_config_file(load_configs.back());
|
||||
// If loading a 3MF file, the config is loaded from the last one.
|
||||
if (!m_input_files.empty())
|
||||
gui->plater()->load_files(m_input_files, true, true);
|
||||
if (!m_extra_config.empty())
|
||||
gui->mainframe->load_config(m_extra_config);
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
}
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
});
|
||||
*/
|
||||
int result = wxEntry(argc, argv);
|
||||
return result;
|
||||
#else /* SLIC3R_GUI */
|
||||
Slic3r::GUI::GUI_InitParams params;
|
||||
params.argc = argc;
|
||||
params.argv = argv;
|
||||
params.load_configs = load_configs;
|
||||
params.extra_config = std::move(m_extra_config);
|
||||
params.input_files = std::move(m_input_files);
|
||||
params.start_as_gcodeviewer = start_as_gcodeviewer;
|
||||
return Slic3r::GUI::GUI_Run(params);
|
||||
#else // SLIC3R_GUI
|
||||
// No GUI support. Just print out a help.
|
||||
this->print_help(false);
|
||||
// If started without a parameter, consider it to be OK, otherwise report an error code (no action etc).
|
||||
return (argc == 0) ? 0 : 1;
|
||||
#endif /* SLIC3R_GUI */
|
||||
#endif // SLIC3R_GUI
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -73,6 +73,8 @@ set(SLIC3R_GUI_SOURCES
|
||||
GUI/PresetHints.hpp
|
||||
GUI/GUI.cpp
|
||||
GUI/GUI.hpp
|
||||
GUI/GUI_Init.cpp
|
||||
GUI/GUI_Init.hpp
|
||||
GUI/GUI_Preview.cpp
|
||||
GUI/GUI_Preview.hpp
|
||||
GUI/GUI_App.cpp
|
||||
|
@ -45,7 +45,7 @@ bool SlicingProcessCompletedEvent::critical_error() const
|
||||
{
|
||||
try {
|
||||
this->rethrow_exception();
|
||||
} catch (const Slic3r::SlicingError &ex) {
|
||||
} catch (const Slic3r::SlicingError &) {
|
||||
// Exception derived from SlicingError is non-critical.
|
||||
return false;
|
||||
} catch (...) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "libslic3r/Technologies.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include "GUI_Init.hpp"
|
||||
#include "GUI_ObjectList.hpp"
|
||||
#include "GUI_ObjectManipulation.hpp"
|
||||
#include "I18N.hpp"
|
||||
@ -538,15 +539,16 @@ static void generic_exception_handle()
|
||||
}
|
||||
}
|
||||
|
||||
void GUI_App::AfterInitLoads::on_loads(GUI_App* gui)
|
||||
void GUI_App::post_init()
|
||||
{
|
||||
if (!gui->initialized())
|
||||
return;
|
||||
assert(initialized());
|
||||
if (! this->initialized())
|
||||
throw Slic3r::RuntimeError("Calling post_init() while not yet initialized");
|
||||
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
if (m_start_as_gcodeviewer) {
|
||||
if (!m_input_files.empty())
|
||||
gui->plater()->load_gcode(wxString::FromUTF8(m_input_files[0].c_str()));
|
||||
if (this->init_params->start_as_gcodeviewer) {
|
||||
if (! this->init_params->input_files.empty())
|
||||
this->plater()->load_gcode(wxString::FromUTF8(this->init_params->input_files[0].c_str()));
|
||||
}
|
||||
else {
|
||||
#endif // ENABLE_GCODE_VIEWER_AS
|
||||
@ -556,22 +558,22 @@ void GUI_App::AfterInitLoads::on_loads(GUI_App* gui)
|
||||
// We need to decide what to do about loading of separate presets (just print preset, just filament preset etc).
|
||||
// As of now only the full configs are supported here.
|
||||
if (!m_print_config.empty())
|
||||
gui->mainframe->load_config(m_print_config);
|
||||
this->gui->mainframe->load_config(m_print_config);
|
||||
#endif
|
||||
if (!m_load_configs.empty())
|
||||
if (! this->init_params->load_configs.empty())
|
||||
// Load the last config to give it a name at the UI. The name of the preset may be later
|
||||
// changed by loading an AMF or 3MF.
|
||||
//FIXME this is not strictly correct, as one may pass a print/filament/printer profile here instead of a full config.
|
||||
gui->mainframe->load_config_file(m_load_configs.back());
|
||||
this->mainframe->load_config_file(this->init_params->load_configs.back());
|
||||
// If loading a 3MF file, the config is loaded from the last one.
|
||||
if (!m_input_files.empty())
|
||||
gui->plater()->load_files(m_input_files, true, true);
|
||||
if (!m_extra_config.empty())
|
||||
gui->mainframe->load_config(m_extra_config);
|
||||
if (! this->init_params->input_files.empty())
|
||||
this->plater()->load_files(this->init_params->input_files, true, true);
|
||||
if (! this->init_params->extra_config.empty())
|
||||
this->mainframe->load_config(this->init_params->extra_config);
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
}
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
}
|
||||
}
|
||||
|
||||
IMPLEMENT_APP(GUI_App)
|
||||
|
||||
@ -647,7 +649,6 @@ void GUI_App::init_app_config()
|
||||
m_app_conf_exists = app_config->exists();
|
||||
if (m_app_conf_exists) {
|
||||
std::string error = app_config->load();
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
if (!error.empty()) {
|
||||
// Error while parsing config file. We'll customize the error message and rethrow to be displayed.
|
||||
if (is_editor()) {
|
||||
@ -663,14 +664,6 @@ void GUI_App::init_app_config()
|
||||
"\n\n" + app_config->config_path() + "\n\n" + error);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (!error.empty())
|
||||
// Error while parsing config file. We'll customize the error message and rethrow to be displayed.
|
||||
throw Slic3r::RuntimeError(
|
||||
_u8L("Error parsing PrusaSlicer config file, it is probably corrupted. "
|
||||
"Try to manually delete the file to recover from the error. Your user profiles will not be affected.") +
|
||||
"\n\n" + AppConfig::config_path() + "\n\n" + error);
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
}
|
||||
}
|
||||
|
||||
@ -855,7 +848,7 @@ bool GUI_App::on_init_inner()
|
||||
#ifdef WIN32
|
||||
this->mainframe->register_win32_callbacks();
|
||||
#endif
|
||||
this->after_init_loads.on_loads(this);
|
||||
this->post_init();
|
||||
}
|
||||
|
||||
// Preset updating & Configwizard are done after the above initializations,
|
||||
|
@ -24,6 +24,7 @@ class wxNotebook;
|
||||
struct wxLanguageInfo;
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class AppConfig;
|
||||
class PresetBundle;
|
||||
class PresetUpdater;
|
||||
@ -32,6 +33,7 @@ class PrintHostJobQueue;
|
||||
class Model;
|
||||
|
||||
namespace GUI{
|
||||
|
||||
class RemovableDriveManager;
|
||||
class OtherInstanceMessageHandler;
|
||||
class MainFrame;
|
||||
@ -41,6 +43,7 @@ class ObjectSettings;
|
||||
class ObjectList;
|
||||
class ObjectLayers;
|
||||
class Plater;
|
||||
struct GUI_InitParams;
|
||||
|
||||
|
||||
|
||||
@ -142,37 +145,6 @@ private:
|
||||
std::string m_instance_hash_string;
|
||||
size_t m_instance_hash_int;
|
||||
|
||||
// parameters needed for the after OnInit() loads
|
||||
struct AfterInitLoads
|
||||
{
|
||||
std::vector<std::string> m_load_configs;
|
||||
DynamicPrintConfig m_extra_config;
|
||||
std::vector<std::string> m_input_files;
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
bool m_start_as_gcodeviewer;
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
|
||||
void set_params(
|
||||
const std::vector<std::string>& load_configs,
|
||||
const DynamicPrintConfig& extra_config,
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
const std::vector<std::string>& input_files,
|
||||
bool start_as_gcodeviewer
|
||||
#else
|
||||
const std::vector<std::string>& input_files
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
) {
|
||||
m_load_configs = load_configs;
|
||||
m_extra_config = extra_config;
|
||||
m_input_files = input_files;
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
m_start_as_gcodeviewer = start_as_gcodeviewer;
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
}
|
||||
|
||||
void on_loads(GUI_App* gui);
|
||||
};
|
||||
|
||||
public:
|
||||
bool OnInit() override;
|
||||
bool initialized() const { return m_initialized; }
|
||||
@ -191,9 +163,13 @@ public:
|
||||
bool is_recreating_gui() const { return m_is_recreating_gui; }
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
|
||||
// To be called after the GUI is fully built up.
|
||||
// Process command line parameters cached in this->init_params,
|
||||
// load configs, STLs etc.
|
||||
void post_init();
|
||||
static std::string get_gl_info(bool format_as_html, bool extensions);
|
||||
wxGLContext* init_glcontext(wxGLCanvas& canvas);
|
||||
bool init_opengl();
|
||||
wxGLContext* init_glcontext(wxGLCanvas& canvas);
|
||||
bool init_opengl();
|
||||
|
||||
static unsigned get_colour_approx_luma(const wxColour &colour);
|
||||
static bool dark_mode();
|
||||
@ -267,12 +243,14 @@ public:
|
||||
Model& model();
|
||||
|
||||
|
||||
// Parameters extracted from the command line to be passed to GUI after initialization.
|
||||
const GUI_InitParams* init_params { nullptr };
|
||||
|
||||
AppConfig* app_config{ nullptr };
|
||||
PresetBundle* preset_bundle{ nullptr };
|
||||
PresetUpdater* preset_updater{ nullptr };
|
||||
MainFrame* mainframe{ nullptr };
|
||||
Plater* plater_{ nullptr };
|
||||
AfterInitLoads after_init_loads;
|
||||
|
||||
PresetUpdater* get_preset_updater() { return preset_updater; }
|
||||
|
||||
|
95
src/slic3r/GUI/GUI_Init.cpp
Normal file
95
src/slic3r/GUI/GUI_Init.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
#include "GUI_Init.hpp"
|
||||
|
||||
#include "libslic3r/AppConfig.hpp"
|
||||
|
||||
#include "slic3r/GUI/GUI.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/3DScene.hpp"
|
||||
#include "slic3r/GUI/InstanceCheck.hpp"
|
||||
#include "slic3r/GUI/format.hpp"
|
||||
#include "slic3r/GUI/MainFrame.hpp"
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
|
||||
// To show a message box if GUI initialization ends up with an exception thrown.
|
||||
#include <wx/msgdlg.h>
|
||||
|
||||
#include <boost/nowide/iostream.hpp>
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
int GUI_Run(GUI_InitParams ¶ms)
|
||||
{
|
||||
try {
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
GUI::GUI_App* gui = new GUI::GUI_App(params.start_as_gcodeviewer ? GUI::GUI_App::EAppMode::GCodeViewer : GUI::GUI_App::EAppMode::Editor);
|
||||
if (gui->get_app_mode() != GUI::GUI_App::EAppMode::GCodeViewer) {
|
||||
// G-code viewer is currently not performing instance check, a new G-code viewer is started every time.
|
||||
bool gui_single_instance_setting = gui->app_config->get("single_instance") == "1";
|
||||
if (Slic3r::instance_check(params.argc, params.argv, gui_single_instance_setting)) {
|
||||
//TODO: do we have delete gui and other stuff?
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
GUI::GUI_App *gui = new GUI::GUI_App();
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
|
||||
// gui->autosave = m_config.opt_string("autosave");
|
||||
GUI::GUI_App::SetInstance(gui);
|
||||
gui->init_params = ¶ms;
|
||||
/*
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
gui->CallAfter([gui, this, &load_configs, params.start_as_gcodeviewer] {
|
||||
#else
|
||||
gui->CallAfter([gui, this, &load_configs] {
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
if (!gui->initialized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
if (params.start_as_gcodeviewer) {
|
||||
if (!m_input_files.empty())
|
||||
gui->plater()->load_gcode(wxString::FromUTF8(m_input_files[0].c_str()));
|
||||
} else {
|
||||
#endif // ENABLE_GCODE_VIEWER_AS
|
||||
#if 0
|
||||
// Load the cummulative config over the currently active profiles.
|
||||
//FIXME if multiple configs are loaded, only the last one will have an effect.
|
||||
// We need to decide what to do about loading of separate presets (just print preset, just filament preset etc).
|
||||
// As of now only the full configs are supported here.
|
||||
if (!m_print_config.empty())
|
||||
gui->mainframe->load_config(m_print_config);
|
||||
#endif
|
||||
if (!load_configs.empty())
|
||||
// Load the last config to give it a name at the UI. The name of the preset may be later
|
||||
// changed by loading an AMF or 3MF.
|
||||
//FIXME this is not strictly correct, as one may pass a print/filament/printer profile here instead of a full config.
|
||||
gui->mainframe->load_config_file(load_configs.back());
|
||||
// If loading a 3MF file, the config is loaded from the last one.
|
||||
if (!m_input_files.empty())
|
||||
gui->plater()->load_files(m_input_files, true, true);
|
||||
if (!m_extra_config.empty())
|
||||
gui->mainframe->load_config(m_extra_config);
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
}
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
});
|
||||
*/
|
||||
int result = wxEntry(params.argc, params.argv);
|
||||
return result;
|
||||
} catch (const Slic3r::Exception &ex) {
|
||||
boost::nowide::cerr << ex.what() << std::endl;
|
||||
wxMessageBox(boost::nowide::widen(ex.what()), _L("PrusaSlicer GUI initialization failed"), wxICON_STOP);
|
||||
} catch (const std::exception &ex) {
|
||||
boost::nowide::cerr << "PrusaSlicer GUI initialization failed: " << ex.what() << std::endl;
|
||||
wxMessageBox(format_wxstr(_L("Fatal error, exception catched: %1%"), ex.what()), _L("PrusaSlicer GUI initialization failed"), wxICON_STOP);
|
||||
}
|
||||
|
||||
// error
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
24
src/slic3r/GUI/GUI_Init.hpp
Normal file
24
src/slic3r/GUI/GUI_Init.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef slic3r_GUI_Init_hpp_
|
||||
#define slic3r_GUI_Init_hpp_
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
struct GUI_InitParams
|
||||
{
|
||||
int argc;
|
||||
char **argv;
|
||||
|
||||
std::vector<std::string> load_configs;
|
||||
DynamicPrintConfig extra_config;
|
||||
std::vector<std::string> input_files;
|
||||
|
||||
bool start_as_gcodeviewer;
|
||||
};
|
||||
|
||||
int GUI_Run(GUI_InitParams ¶ms);
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif slic3r_GUI_Init_hpp_
|
Loading…
Reference in New Issue
Block a user