mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	Merge branch 'dk_notifications'
This commit is contained in:
		
						commit
						15ba458f2c
					
				
					 9 changed files with 275 additions and 66 deletions
				
			
		| 
						 | 
				
			
			@ -122,9 +122,9 @@ void AppConfig::set_defaults()
 | 
			
		|||
        if (get("auto_toolbar_size").empty())
 | 
			
		||||
            set("auto_toolbar_size", "100");
 | 
			
		||||
 
 | 
			
		||||
       if (get("notify_release").empty())
 | 
			
		||||
           set("notify_release", "all"); // or "none" or "release"
 | 
			
		||||
 | 
			
		||||
       if (get("notify_testing_release").empty())
 | 
			
		||||
           set("notify_testing_release", "1");
 | 
			
		||||
#if ENABLE_ENVIRONMENT_MAP
 | 
			
		||||
        if (get("use_environment_map").empty())
 | 
			
		||||
            set("use_environment_map", "0");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -919,7 +919,6 @@ bool GUI_App::on_init_inner()
 | 
			
		|||
            }
 | 
			
		||||
            });
 | 
			
		||||
        Bind(EVT_SLIC3R_ALPHA_VERSION_ONLINE, [this](const wxCommandEvent& evt) {
 | 
			
		||||
            //app_config->set("version_alpha_online", into_u8(evt.GetString()));
 | 
			
		||||
            app_config->save();
 | 
			
		||||
            if (this->plater_ != nullptr && app_config->get("notify_testing_release") == "1") {
 | 
			
		||||
                if (*Semver::parse(SLIC3R_VERSION) < *Semver::parse(into_u8(evt.GetString()))) {
 | 
			
		||||
| 
						 | 
				
			
			@ -928,7 +927,6 @@ bool GUI_App::on_init_inner()
 | 
			
		|||
            }
 | 
			
		||||
            });
 | 
			
		||||
        Bind(EVT_SLIC3R_BETA_VERSION_ONLINE, [this](const wxCommandEvent& evt) {
 | 
			
		||||
            //app_config->set("version_beta_online", into_u8(evt.GetString()));
 | 
			
		||||
            app_config->save();
 | 
			
		||||
            if (this->plater_ != nullptr && app_config->get("notify_testing_release") == "1") {
 | 
			
		||||
                if (*Semver::parse(SLIC3R_VERSION) < *Semver::parse(into_u8(evt.GetString()))) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,6 +72,11 @@ void OG_CustomCtrl::init_ctrl_lines()
 | 
			
		|||
    const std::vector<Line>& og_lines = opt_group->get_lines();
 | 
			
		||||
    for (const Line& line : og_lines)
 | 
			
		||||
    {
 | 
			
		||||
        if (line.is_separator()) {
 | 
			
		||||
            ctrl_lines.emplace_back(CtrlLine(0, this, line));
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (line.full_width && (
 | 
			
		||||
            // description line
 | 
			
		||||
            line.widget != nullptr ||
 | 
			
		||||
| 
						 | 
				
			
			@ -124,6 +129,15 @@ wxPoint OG_CustomCtrl::get_pos(const Line& line, Field* field_in/* = nullptr*/)
 | 
			
		|||
            line_height = win_height;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    auto correct_horiz_pos = [this](int& h_pos, Field* field) {
 | 
			
		||||
        if (m_max_win_width > 0 && field->getWindow()) {
 | 
			
		||||
            int win_width = field->getWindow()->GetSize().GetWidth();
 | 
			
		||||
            if (dynamic_cast<CheckBox*>(field))
 | 
			
		||||
                win_width *= 0.5;
 | 
			
		||||
            h_pos += m_max_win_width - win_width;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    for (CtrlLine& ctrl_line : ctrl_lines) {
 | 
			
		||||
        if (&ctrl_line.og_line == &line)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -160,6 +174,7 @@ wxPoint OG_CustomCtrl::get_pos(const Line& line, Field* field_in/* = nullptr*/)
 | 
			
		|||
                h_pos += 3 * blinking_button_width;
 | 
			
		||||
                Field* field = opt_group->get_field(option_set.front().opt_id);
 | 
			
		||||
                correct_line_height(ctrl_line.height, field->getWindow());
 | 
			
		||||
                correct_horiz_pos(h_pos, field);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -189,8 +204,10 @@ wxPoint OG_CustomCtrl::get_pos(const Line& line, Field* field_in/* = nullptr*/)
 | 
			
		|||
                }                
 | 
			
		||||
                h_pos += (opt.opt.gui_type == ConfigOptionDef::GUIType::legend ? 1 : 3) * blinking_button_width;
 | 
			
		||||
                
 | 
			
		||||
                if (field == field_in)
 | 
			
		||||
                if (field == field_in) {
 | 
			
		||||
                    correct_horiz_pos(h_pos, field);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                if (opt.opt.gui_type == ConfigOptionDef::GUIType::legend)
 | 
			
		||||
                    h_pos += 2 * blinking_button_width;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -361,6 +378,28 @@ void OG_CustomCtrl::correct_widgets_position(wxSizer* widget, const Line& line,
 | 
			
		|||
        }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void OG_CustomCtrl::init_max_win_width()
 | 
			
		||||
{
 | 
			
		||||
    if (opt_group->ctrl_horiz_alignment == wxALIGN_RIGHT && m_max_win_width == 0)
 | 
			
		||||
        for (CtrlLine& line : ctrl_lines) {
 | 
			
		||||
            if (int max_win_width = line.get_max_win_width();
 | 
			
		||||
                m_max_win_width < max_win_width)
 | 
			
		||||
                m_max_win_width = max_win_width;
 | 
			
		||||
        }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OG_CustomCtrl::set_max_win_width(int max_win_width)
 | 
			
		||||
{
 | 
			
		||||
    if (m_max_win_width == max_win_width)
 | 
			
		||||
        return;
 | 
			
		||||
    m_max_win_width = max_win_width;
 | 
			
		||||
    for (CtrlLine& line : ctrl_lines)
 | 
			
		||||
        line.correct_items_positions();
 | 
			
		||||
 | 
			
		||||
    GetParent()->Layout();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void OG_CustomCtrl::msw_rescale()
 | 
			
		||||
{
 | 
			
		||||
#ifdef __WXOSX__
 | 
			
		||||
| 
						 | 
				
			
			@ -374,6 +413,8 @@ void OG_CustomCtrl::msw_rescale()
 | 
			
		|||
    m_bmp_mode_sz = create_scaled_bitmap("mode_simple", this, wxOSX ? 10 : 12).GetSize();
 | 
			
		||||
    m_bmp_blinking_sz = create_scaled_bitmap("search_blink", this).GetSize();
 | 
			
		||||
 | 
			
		||||
    m_max_win_width = 0;
 | 
			
		||||
 | 
			
		||||
    wxCoord    v_pos = 0;
 | 
			
		||||
    for (CtrlLine& line : ctrl_lines) {
 | 
			
		||||
        line.msw_rescale();
 | 
			
		||||
| 
						 | 
				
			
			@ -407,6 +448,21 @@ OG_CustomCtrl::CtrlLine::CtrlLine(  wxCoord         height,
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int OG_CustomCtrl::CtrlLine::get_max_win_width()
 | 
			
		||||
{
 | 
			
		||||
    int max_win_width = 0;
 | 
			
		||||
    if (!draw_just_act_buttons) {
 | 
			
		||||
        const std::vector<Option>& option_set = og_line.get_options();
 | 
			
		||||
        for (auto opt : option_set) {
 | 
			
		||||
            Field* field = ctrl->opt_group->get_field(opt.opt_id);
 | 
			
		||||
            if (field && field->getWindow())
 | 
			
		||||
                max_win_width = field->getWindow()->GetSize().GetWidth();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return max_win_width;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OG_CustomCtrl::CtrlLine::correct_items_positions()
 | 
			
		||||
{
 | 
			
		||||
    if (draw_just_act_buttons || !is_visible)
 | 
			
		||||
| 
						 | 
				
			
			@ -447,6 +503,8 @@ void OG_CustomCtrl::CtrlLine::msw_rescale()
 | 
			
		|||
 | 
			
		||||
void OG_CustomCtrl::CtrlLine::update_visibility(ConfigOptionMode mode)
 | 
			
		||||
{
 | 
			
		||||
    if (og_line.is_separator())
 | 
			
		||||
        return;
 | 
			
		||||
    const std::vector<Option>& option_set = og_line.get_options();
 | 
			
		||||
 | 
			
		||||
    const ConfigOptionMode& line_mode = option_set.front().opt.mode;
 | 
			
		||||
| 
						 | 
				
			
			@ -480,8 +538,25 @@ void OG_CustomCtrl::CtrlLine::update_visibility(ConfigOptionMode mode)
 | 
			
		|||
    correct_items_positions();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OG_CustomCtrl::CtrlLine::render_separator(wxDC& dc, wxCoord v_pos)
 | 
			
		||||
{
 | 
			
		||||
    wxPoint begin(ctrl->m_h_gap, v_pos);
 | 
			
		||||
    wxPoint end(ctrl->GetSize().GetWidth() - ctrl->m_h_gap, v_pos);
 | 
			
		||||
 | 
			
		||||
    wxPen pen, old_pen = pen = dc.GetPen();
 | 
			
		||||
    pen.SetColour(*wxLIGHT_GREY);
 | 
			
		||||
    dc.SetPen(pen);
 | 
			
		||||
    dc.DrawLine(begin, end);
 | 
			
		||||
    dc.SetPen(old_pen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OG_CustomCtrl::CtrlLine::render(wxDC& dc, wxCoord v_pos)
 | 
			
		||||
{
 | 
			
		||||
    if (is_separator()) {
 | 
			
		||||
        render_separator(dc, v_pos);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Field* field = ctrl->opt_group->get_field(og_line.get_options().front().opt_id);
 | 
			
		||||
 | 
			
		||||
    bool suppress_hyperlinks = get_app_config()->get("suppress_hyperlinks") == "1";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,6 +33,8 @@ class OG_CustomCtrl :public wxPanel
 | 
			
		|||
    wxSize  m_bmp_mode_sz;
 | 
			
		||||
    wxSize  m_bmp_blinking_sz;
 | 
			
		||||
 | 
			
		||||
    int     m_max_win_width{0};
 | 
			
		||||
 | 
			
		||||
    struct CtrlLine {
 | 
			
		||||
        wxCoord           height  { wxDefaultCoord };
 | 
			
		||||
        OG_CustomCtrl*    ctrl    { nullptr };
 | 
			
		||||
| 
						 | 
				
			
			@ -50,16 +52,20 @@ class OG_CustomCtrl :public wxPanel
 | 
			
		|||
                    bool            draw_mode_bitmap = true);
 | 
			
		||||
        ~CtrlLine() { ctrl = nullptr; }
 | 
			
		||||
 | 
			
		||||
        int     get_max_win_width();
 | 
			
		||||
        void    correct_items_positions();
 | 
			
		||||
        void    msw_rescale();
 | 
			
		||||
        void    update_visibility(ConfigOptionMode mode);
 | 
			
		||||
 | 
			
		||||
        void render_separator(wxDC& dc, wxCoord v_pos);
 | 
			
		||||
 | 
			
		||||
        void    render(wxDC& dc, wxCoord v_pos);
 | 
			
		||||
        wxCoord draw_mode_bmp(wxDC& dc, wxCoord v_pos);
 | 
			
		||||
        wxCoord draw_text      (wxDC& dc, wxPoint pos, const wxString& text, const wxColour* color, int width, bool is_url = false);
 | 
			
		||||
        wxPoint draw_blinking_bmp(wxDC& dc, wxPoint pos, bool is_blinking);
 | 
			
		||||
        wxCoord draw_act_bmps(wxDC& dc, wxPoint pos, const wxBitmap& bmp_undo_to_sys, const wxBitmap& bmp_undo, bool is_blinking, size_t rect_id = 0);
 | 
			
		||||
        bool    launch_browser() const;
 | 
			
		||||
        bool    is_separator() const { return og_line.is_separator(); }
 | 
			
		||||
 | 
			
		||||
        std::vector<wxRect> rects_undo_icon;
 | 
			
		||||
        std::vector<wxRect> rects_undo_to_sys_icon;
 | 
			
		||||
| 
						 | 
				
			
			@ -86,6 +92,9 @@ public:
 | 
			
		|||
    bool    update_visibility(ConfigOptionMode mode);
 | 
			
		||||
    void    correct_window_position(wxWindow* win, const Line& line, Field* field = nullptr);
 | 
			
		||||
    void    correct_widgets_position(wxSizer* widget, const Line& line, Field* field = nullptr);
 | 
			
		||||
    void    init_max_win_width();
 | 
			
		||||
    void    set_max_win_width(int max_win_width);
 | 
			
		||||
    int     get_max_win_width() { return m_max_win_width; }
 | 
			
		||||
 | 
			
		||||
    void    msw_rescale();
 | 
			
		||||
    void    sys_color_changed();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -126,6 +126,12 @@ bool OptionsGroup::is_legend_line()
 | 
			
		|||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OptionsGroup::set_max_win_width(int max_win_width)
 | 
			
		||||
{
 | 
			
		||||
    if (custom_ctrl)
 | 
			
		||||
        custom_ctrl->set_max_win_width(max_win_width);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OptionsGroup::show_field(const t_config_option_key& opt_key, bool show/* = true*/)
 | 
			
		||||
{
 | 
			
		||||
    Field* field = get_field(opt_key);
 | 
			
		||||
| 
						 | 
				
			
			@ -185,8 +191,16 @@ void OptionsGroup::append_line(const Line& line)
 | 
			
		|||
        m_options_mode.push_back(option_set[0].opt.mode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OptionsGroup::append_separator()
 | 
			
		||||
{
 | 
			
		||||
    m_lines.emplace_back(Line());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OptionsGroup::activate_line(Line& line)
 | 
			
		||||
{
 | 
			
		||||
    if (line.is_separator())
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
	m_use_custom_ctrl_as_parent = false;
 | 
			
		||||
 | 
			
		||||
	if (line.full_width && (
 | 
			
		||||
| 
						 | 
				
			
			@ -396,7 +410,7 @@ void OptionsGroup::activate_line(Line& line)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// create all controls for the option group from the m_lines
 | 
			
		||||
bool OptionsGroup::activate(std::function<void()> throw_if_canceled)
 | 
			
		||||
bool OptionsGroup::activate(std::function<void()> throw_if_canceled/* = [](){}*/, int horiz_alignment/* = wxALIGN_LEFT*/)
 | 
			
		||||
{
 | 
			
		||||
	if (sizer)//(!sizer->IsEmpty())
 | 
			
		||||
		return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -436,6 +450,10 @@ bool OptionsGroup::activate(std::function<void()> throw_if_canceled)
 | 
			
		|||
			throw_if_canceled();
 | 
			
		||||
			activate_line(line);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        ctrl_horiz_alignment = horiz_alignment;
 | 
			
		||||
        if (custom_ctrl)
 | 
			
		||||
            custom_ctrl->init_max_win_width();
 | 
			
		||||
	} catch (UIBuildCanceled&) {
 | 
			
		||||
		auto p = sizer;
 | 
			
		||||
		this->clear();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,6 +49,7 @@ using t_option = std::unique_ptr<Option>;	//!
 | 
			
		|||
 | 
			
		||||
/// Represents option lines
 | 
			
		||||
class Line {
 | 
			
		||||
	bool		m_is_separator{ false };
 | 
			
		||||
public:
 | 
			
		||||
    wxString	label;
 | 
			
		||||
    wxString	label_tooltip;
 | 
			
		||||
| 
						 | 
				
			
			@ -71,6 +72,9 @@ public:
 | 
			
		|||
    }
 | 
			
		||||
	Line(wxString label, wxString tooltip) :
 | 
			
		||||
		label(_(label)), label_tooltip(_(tooltip)) {}
 | 
			
		||||
	Line() : m_is_separator(true) {}
 | 
			
		||||
 | 
			
		||||
	bool is_separator() const { return m_is_separator; }
 | 
			
		||||
 | 
			
		||||
    const std::vector<widget_t>&	get_extra_widgets() const {return m_extra_widgets;}
 | 
			
		||||
    const std::vector<Option>&		get_options() const { return m_options; }
 | 
			
		||||
| 
						 | 
				
			
			@ -95,6 +99,7 @@ public:
 | 
			
		|||
    size_t			label_width = 20 ;// {200};
 | 
			
		||||
    wxSizer*		sizer {nullptr};
 | 
			
		||||
	OG_CustomCtrl*  custom_ctrl{ nullptr };
 | 
			
		||||
	int				ctrl_horiz_alignment{ wxALIGN_LEFT};
 | 
			
		||||
    column_t		extra_column {nullptr};
 | 
			
		||||
    t_change		m_on_change { nullptr };
 | 
			
		||||
	// To be called when the field loses focus, to assign a new initial value to the field.
 | 
			
		||||
| 
						 | 
				
			
			@ -124,12 +129,13 @@ public:
 | 
			
		|||
	void		activate_line(Line& line);
 | 
			
		||||
 | 
			
		||||
	// create all controls for the option group from the m_lines
 | 
			
		||||
	bool		activate(std::function<void()> throw_if_canceled = [](){});
 | 
			
		||||
	bool		activate(std::function<void()> throw_if_canceled = [](){}, int horiz_alignment = wxALIGN_LEFT);
 | 
			
		||||
	// delete all controls from the option group
 | 
			
		||||
	void		clear(bool destroy_custom_ctrl = false);
 | 
			
		||||
 | 
			
		||||
    Line		create_single_option_line(const Option& option, const wxString& path = wxEmptyString) const;
 | 
			
		||||
    void		append_single_option_line(const Option& option, const wxString& path = wxEmptyString) { append_line(create_single_option_line(option, path)); }
 | 
			
		||||
	void		append_separator();
 | 
			
		||||
 | 
			
		||||
    // return a non-owning pointer reference 
 | 
			
		||||
    inline Field*	get_field(const t_config_option_key& id) const{
 | 
			
		||||
| 
						 | 
				
			
			@ -171,6 +177,9 @@ public:
 | 
			
		|||
    wxGridSizer*        get_grid_sizer() { return m_grid_sizer; }
 | 
			
		||||
	const std::vector<Line>& get_lines() { return m_lines; }
 | 
			
		||||
	bool				is_legend_line();
 | 
			
		||||
	// if we have to set the same control alignment for different option groups, 
 | 
			
		||||
    // we have to set same max contrtol width to all of them
 | 
			
		||||
	void				set_max_win_width(int max_win_width);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
	std::map<t_config_option_key, Option>	m_options;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,8 +8,38 @@
 | 
			
		|||
#include <wx/notebook.h>
 | 
			
		||||
#include "Notebook.hpp"
 | 
			
		||||
#include "ButtonsDescription.hpp"
 | 
			
		||||
#include "OG_CustomCtrl.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Slic3r {
 | 
			
		||||
 | 
			
		||||
	static t_config_enum_names enum_names_from_keys_map(const t_config_enum_values& enum_keys_map)
 | 
			
		||||
	{
 | 
			
		||||
		t_config_enum_names names;
 | 
			
		||||
		int cnt = 0;
 | 
			
		||||
		for (const auto& kvp : enum_keys_map)
 | 
			
		||||
			cnt = std::max(cnt, kvp.second);
 | 
			
		||||
		cnt += 1;
 | 
			
		||||
		names.assign(cnt, "");
 | 
			
		||||
		for (const auto& kvp : enum_keys_map)
 | 
			
		||||
			names[kvp.second] = kvp.first;
 | 
			
		||||
		return names;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#define CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(NAME) \
 | 
			
		||||
    static t_config_enum_names s_keys_names_##NAME = enum_names_from_keys_map(s_keys_map_##NAME); \
 | 
			
		||||
    template<> const t_config_enum_values& ConfigOptionEnum<NAME>::get_enum_values() { return s_keys_map_##NAME; } \
 | 
			
		||||
    template<> const t_config_enum_names& ConfigOptionEnum<NAME>::get_enum_names() { return s_keys_names_##NAME; }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	static const t_config_enum_values s_keys_map_NotifyReleaseMode = {
 | 
			
		||||
		{"all",         NotifyReleaseAll},
 | 
			
		||||
		{"release",     NotifyReleaseOnly},
 | 
			
		||||
		{"none",        NotifyReleaseNone},
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(NotifyReleaseMode)
 | 
			
		||||
 | 
			
		||||
namespace GUI {
 | 
			
		||||
 | 
			
		||||
PreferencesDialog::PreferencesDialog(wxWindow* parent, int selected_tab) :
 | 
			
		||||
| 
						 | 
				
			
			@ -39,7 +69,7 @@ static std::shared_ptr<ConfigOptionsGroup>create_options_tab(const wxString& tit
 | 
			
		|||
 | 
			
		||||
static void activate_options_tab(std::shared_ptr<ConfigOptionsGroup> optgroup)
 | 
			
		||||
{
 | 
			
		||||
	optgroup->activate();
 | 
			
		||||
	optgroup->activate([](){}, wxALIGN_RIGHT);
 | 
			
		||||
	optgroup->update_visibility(comSimple);
 | 
			
		||||
	wxBoxSizer* sizer = static_cast<wxBoxSizer*>(static_cast<wxPanel*>(optgroup->parent())->GetSizer());
 | 
			
		||||
	sizer->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 10);
 | 
			
		||||
| 
						 | 
				
			
			@ -116,6 +146,8 @@ void PreferencesDialog::build(size_t selected_tab)
 | 
			
		|||
		option = Option(def, "version_check");
 | 
			
		||||
		m_optgroup_general->append_single_option_line(option);
 | 
			
		||||
 | 
			
		||||
		m_optgroup_general->append_separator();
 | 
			
		||||
 | 
			
		||||
		// Please keep in sync with ConfigWizard
 | 
			
		||||
		def.label = L("Export sources full pathnames to 3mf and amf");
 | 
			
		||||
		def.type = coBool;
 | 
			
		||||
| 
						 | 
				
			
			@ -141,6 +173,8 @@ void PreferencesDialog::build(size_t selected_tab)
 | 
			
		|||
		m_optgroup_general->append_single_option_line(option);
 | 
			
		||||
#endif // _WIN32
 | 
			
		||||
 | 
			
		||||
		m_optgroup_general->append_separator();
 | 
			
		||||
 | 
			
		||||
		// Please keep in sync with ConfigWizard
 | 
			
		||||
		def.label = L("Update built-in Presets automatically");
 | 
			
		||||
		def.type = coBool;
 | 
			
		||||
| 
						 | 
				
			
			@ -165,6 +199,8 @@ void PreferencesDialog::build(size_t selected_tab)
 | 
			
		|||
		option = Option(def, "show_incompatible_presets");
 | 
			
		||||
		m_optgroup_general->append_single_option_line(option);
 | 
			
		||||
 | 
			
		||||
		m_optgroup_general->append_separator();
 | 
			
		||||
 | 
			
		||||
		def.label = L("Show drop project dialog");
 | 
			
		||||
		def.type = coBool;
 | 
			
		||||
		def.tooltip = L("When checked, whenever dragging and dropping a project file on the application, shows a dialog asking to select the action to take on the file to load.");
 | 
			
		||||
| 
						 | 
				
			
			@ -172,7 +208,6 @@ void PreferencesDialog::build(size_t selected_tab)
 | 
			
		|||
		option = Option(def, "show_drop_project_dialog");
 | 
			
		||||
		m_optgroup_general->append_single_option_line(option);
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
#if __APPLE__
 | 
			
		||||
		def.label = L("Allow just a single PrusaSlicer instance");
 | 
			
		||||
		def.type = coBool;
 | 
			
		||||
| 
						 | 
				
			
			@ -186,6 +221,8 @@ void PreferencesDialog::build(size_t selected_tab)
 | 
			
		|||
		option = Option(def, "single_instance");
 | 
			
		||||
		m_optgroup_general->append_single_option_line(option);
 | 
			
		||||
 | 
			
		||||
		m_optgroup_general->append_separator();
 | 
			
		||||
 | 
			
		||||
		def.label = L("Ask for unsaved changes when closing application or loading new project");
 | 
			
		||||
		def.type = coBool;
 | 
			
		||||
		def.tooltip = L("Always ask for unsaved changes, when: \n"
 | 
			
		||||
| 
						 | 
				
			
			@ -230,6 +267,8 @@ void PreferencesDialog::build(size_t selected_tab)
 | 
			
		|||
	m_optgroup_general->append_single_option_line(option);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	m_optgroup_general->append_separator();
 | 
			
		||||
 | 
			
		||||
    // Show/Hide splash screen
 | 
			
		||||
	def.label = L("Show splash screen");
 | 
			
		||||
	def.type = coBool;
 | 
			
		||||
| 
						 | 
				
			
			@ -291,7 +330,15 @@ void PreferencesDialog::build(size_t selected_tab)
 | 
			
		|||
	m_optgroup_gui->m_on_change = [this, tabs](t_config_option_key opt_key, boost::any value) {
 | 
			
		||||
        if (opt_key == "suppress_hyperlinks")
 | 
			
		||||
            m_values[opt_key] = boost::any_cast<bool>(value) ? "1" : "";
 | 
			
		||||
        else
 | 
			
		||||
		else if (opt_key == "notify_release") {
 | 
			
		||||
			int val_int = boost::any_cast<int>(value);
 | 
			
		||||
			for (const auto& item : s_keys_map_NotifyReleaseMode) {
 | 
			
		||||
				if (item.second == val_int) {
 | 
			
		||||
					m_values[opt_key] = item.first;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else
 | 
			
		||||
            m_values[opt_key] = boost::any_cast<bool>(value) ? "1" : "0";
 | 
			
		||||
 | 
			
		||||
		if (opt_key == "use_custom_toolbar_size") {
 | 
			
		||||
| 
						 | 
				
			
			@ -300,6 +347,8 @@ void PreferencesDialog::build(size_t selected_tab)
 | 
			
		|||
			tabs->Layout();
 | 
			
		||||
			this->layout();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	def.label = L("Sequential slider applied only to top layer");
 | 
			
		||||
| 
						 | 
				
			
			@ -362,6 +411,8 @@ void PreferencesDialog::build(size_t selected_tab)
 | 
			
		|||
		m_optgroup_gui->append_single_option_line(option);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		m_optgroup_gui->append_separator();
 | 
			
		||||
 | 
			
		||||
		def.label = L("Show \"Tip of the day\" notification after start");
 | 
			
		||||
		def.type = coBool;
 | 
			
		||||
		def.tooltip = L("If enabled, useful hints are displayed at startup.");
 | 
			
		||||
| 
						 | 
				
			
			@ -369,6 +420,24 @@ void PreferencesDialog::build(size_t selected_tab)
 | 
			
		|||
		option = Option(def, "show_hints");
 | 
			
		||||
		m_optgroup_gui->append_single_option_line(option);
 | 
			
		||||
 | 
			
		||||
		ConfigOptionDef def_enum;
 | 
			
		||||
		def_enum.label = L("Notify about new releases");
 | 
			
		||||
		def_enum.type = coEnum;
 | 
			
		||||
		def_enum.tooltip = L("You will be notified about new release after startup acordingly: All = Regular release and alpha / beta releases. Release only = regular release.");
 | 
			
		||||
		def_enum.enum_keys_map = &ConfigOptionEnum<NotifyReleaseMode>::get_enum_values();
 | 
			
		||||
		def_enum.enum_values.push_back("all");
 | 
			
		||||
		def_enum.enum_values.push_back("release");
 | 
			
		||||
		def_enum.enum_values.push_back("none");
 | 
			
		||||
		def_enum.enum_labels.push_back(L("All"));
 | 
			
		||||
		def_enum.enum_labels.push_back(L("Release only"));
 | 
			
		||||
		def_enum.enum_labels.push_back(L("None"));
 | 
			
		||||
		def_enum.mode = comSimple;
 | 
			
		||||
		def_enum.set_default_value(new ConfigOptionEnum<NotifyReleaseMode>(static_cast<NotifyReleaseMode>(s_keys_map_NotifyReleaseMode.at(app_config->get("notify_release")))));
 | 
			
		||||
		option = Option(def_enum, "notify_release");
 | 
			
		||||
		m_optgroup_gui->append_single_option_line(option);
 | 
			
		||||
 | 
			
		||||
		m_optgroup_gui->append_separator();
 | 
			
		||||
 | 
			
		||||
		def.label = L("Use custom size for toolbar icons");
 | 
			
		||||
		def.type = coBool;
 | 
			
		||||
		def.tooltip = L("If enabled, you can change size of toolbar icons manually.");
 | 
			
		||||
| 
						 | 
				
			
			@ -376,15 +445,12 @@ void PreferencesDialog::build(size_t selected_tab)
 | 
			
		|||
		option = Option(def, "use_custom_toolbar_size");
 | 
			
		||||
		m_optgroup_gui->append_single_option_line(option);	
 | 
			
		||||
 | 
			
		||||
		def.label = L("Notify about testing releases");
 | 
			
		||||
		def.type = coBool;
 | 
			
		||||
		def.tooltip = L("If enabled, you will be notified about alpha / beta releases available for download.");
 | 
			
		||||
		def.set_default_value(new ConfigOptionBool{ app_config->get("notify_testing_release") == "1" });
 | 
			
		||||
		option = Option(def, "notify_testing_release");
 | 
			
		||||
		m_optgroup_gui->append_single_option_line(option);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	activate_options_tab(m_optgroup_gui);
 | 
			
		||||
	// set Field for notify_release to its value to activate the object
 | 
			
		||||
	boost::any val = s_keys_map_NotifyReleaseMode.at(app_config->get("notify_release"));
 | 
			
		||||
	m_optgroup_gui->get_field("notify_release")->set_value(val, false);
 | 
			
		||||
 | 
			
		||||
	if (is_editor) {
 | 
			
		||||
		create_icon_size_slider();
 | 
			
		||||
| 
						 | 
				
			
			@ -413,6 +479,9 @@ void PreferencesDialog::build(size_t selected_tab)
 | 
			
		|||
	}
 | 
			
		||||
#endif // ENABLE_ENVIRONMENT_MAP
 | 
			
		||||
 | 
			
		||||
	// update alignment of the controls for all tabs
 | 
			
		||||
	update_ctrls_alignment();
 | 
			
		||||
 | 
			
		||||
	if (selected_tab < tabs->GetPageCount())
 | 
			
		||||
		tabs->SetSelection(selected_tab);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -432,6 +501,20 @@ void PreferencesDialog::build(size_t selected_tab)
 | 
			
		|||
	this->CenterOnParent();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PreferencesDialog::update_ctrls_alignment()
 | 
			
		||||
{
 | 
			
		||||
	int max_ctrl_width{ 0 };
 | 
			
		||||
	std::initializer_list og_list = { m_optgroup_general.get(), m_optgroup_camera.get(), m_optgroup_gui.get() };
 | 
			
		||||
	for (auto og : og_list) {
 | 
			
		||||
		if (int max = og->custom_ctrl->get_max_win_width();
 | 
			
		||||
			max_ctrl_width < max)
 | 
			
		||||
			max_ctrl_width = max;
 | 
			
		||||
	}
 | 
			
		||||
	if (max_ctrl_width)
 | 
			
		||||
		for (auto og : og_list)
 | 
			
		||||
			og->custom_ctrl->set_max_win_width(max_ctrl_width);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PreferencesDialog::accept(wxEvent&)
 | 
			
		||||
{
 | 
			
		||||
//	if (m_values.find("no_defaults") != m_values.end()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,6 +10,13 @@
 | 
			
		|||
class wxColourPickerCtrl;
 | 
			
		||||
 | 
			
		||||
namespace Slic3r {
 | 
			
		||||
 | 
			
		||||
	enum  NotifyReleaseMode {
 | 
			
		||||
		NotifyReleaseAll,
 | 
			
		||||
		NotifyReleaseOnly,
 | 
			
		||||
		NotifyReleaseNone
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
namespace GUI {
 | 
			
		||||
 | 
			
		||||
class ConfigOptionsGroup;
 | 
			
		||||
| 
						 | 
				
			
			@ -39,6 +46,7 @@ public:
 | 
			
		|||
	bool seq_top_layer_only_changed() const { return m_seq_top_layer_only_changed; }
 | 
			
		||||
	bool recreate_GUI() const { return m_recreate_GUI; }
 | 
			
		||||
	void	build(size_t selected_tab = 0);
 | 
			
		||||
	void	update_ctrls_alignment();
 | 
			
		||||
	void	accept(wxEvent&);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -168,6 +168,7 @@ struct PresetUpdater::priv
 | 
			
		|||
	bool get_file(const std::string &url, const fs::path &target_path) const;
 | 
			
		||||
	void prune_tmps() const;
 | 
			
		||||
	void sync_version() const;
 | 
			
		||||
	void parse_version_string(const std::string& body) const;
 | 
			
		||||
	void sync_config(const VendorMap vendors);
 | 
			
		||||
 | 
			
		||||
	void check_install_indices() const;
 | 
			
		||||
| 
						 | 
				
			
			@ -263,60 +264,68 @@ void PresetUpdater::priv::sync_version() const
 | 
			
		|||
		})
 | 
			
		||||
		.on_complete([&](std::string body, unsigned /* http_status */) {
 | 
			
		||||
			boost::trim(body);
 | 
			
		||||
			// release version
 | 
			
		||||
			std::string version;
 | 
			
		||||
			const auto first_nl_pos = body.find_first_of("\n\r");
 | 
			
		||||
			if (first_nl_pos != std::string::npos)
 | 
			
		||||
				version = body.substr(0,first_nl_pos);
 | 
			
		||||
			else
 | 
			
		||||
				version = body;
 | 
			
		||||
			if (! Semver::parse(version)) {
 | 
			
		||||
				BOOST_LOG_TRIVIAL(warning) << format("Received invalid contents from `%1%`: Not a correct semver: `%2%`", SLIC3R_APP_NAME, version);
 | 
			
		||||
			parse_version_string(body);
 | 
			
		||||
		})
 | 
			
		||||
		.perform_sync();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Parses version string obtained in sync_version() and sends events to UI thread.
 | 
			
		||||
// Version string must contain release version on first line. Follows non-mandatory alpha / beta releases on following lines (alpha=2.0.0-alpha1).
 | 
			
		||||
void PresetUpdater::priv::parse_version_string(const std::string& body) const
 | 
			
		||||
{
 | 
			
		||||
	// release version
 | 
			
		||||
	std::string version;
 | 
			
		||||
	const auto first_nl_pos = body.find_first_of("\n\r");
 | 
			
		||||
	if (first_nl_pos != std::string::npos)
 | 
			
		||||
		version = body.substr(0, first_nl_pos);
 | 
			
		||||
	else
 | 
			
		||||
		version = body;
 | 
			
		||||
	if (!Semver::parse(version)) {
 | 
			
		||||
		BOOST_LOG_TRIVIAL(warning) << format("Received invalid contents from `%1%`: Not a correct semver: `%2%`", SLIC3R_APP_NAME, version);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	BOOST_LOG_TRIVIAL(info) << format("Got %1% online version: `%2%`. Sending to GUI thread...", SLIC3R_APP_NAME, version);
 | 
			
		||||
	wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_VERSION_ONLINE);
 | 
			
		||||
	evt->SetString(GUI::from_u8(version));
 | 
			
		||||
	GUI::wxGetApp().QueueEvent(evt);
 | 
			
		||||
 | 
			
		||||
	// alpha / beta version
 | 
			
		||||
	size_t nexn_nl_pos = first_nl_pos;
 | 
			
		||||
	while (nexn_nl_pos != std::string::npos && body.size() > nexn_nl_pos + 1) {
 | 
			
		||||
		const auto last_nl_pos = nexn_nl_pos;
 | 
			
		||||
		nexn_nl_pos = body.find_first_of("\n\r", last_nl_pos + 1);
 | 
			
		||||
		std::string line;
 | 
			
		||||
		if (nexn_nl_pos == std::string::npos)
 | 
			
		||||
			line = body.substr(last_nl_pos + 1);
 | 
			
		||||
		else
 | 
			
		||||
			line = body.substr(last_nl_pos + 1, nexn_nl_pos - last_nl_pos - 1);
 | 
			
		||||
 | 
			
		||||
		// alpha
 | 
			
		||||
		if (line.substr(0, 6) == "alpha=") {
 | 
			
		||||
			version = line.substr(6);
 | 
			
		||||
			if (!Semver::parse(version)) {
 | 
			
		||||
				BOOST_LOG_TRIVIAL(warning) << format("Received invalid contents for alpha release from `%1%`: Not a correct semver: `%2%`", SLIC3R_APP_NAME, version);
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			BOOST_LOG_TRIVIAL(info) << format("Got %1% online version: `%2%`. Sending to GUI thread...", SLIC3R_APP_NAME, version);
 | 
			
		||||
			wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_VERSION_ONLINE);
 | 
			
		||||
			BOOST_LOG_TRIVIAL(info) << format("Got %1% online version of alpha release: `%2%`. Sending to GUI thread...", SLIC3R_APP_NAME, version);
 | 
			
		||||
			wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_ALPHA_VERSION_ONLINE);
 | 
			
		||||
			evt->SetString(GUI::from_u8(version));
 | 
			
		||||
			GUI::wxGetApp().QueueEvent(evt);
 | 
			
		||||
 | 
			
		||||
			// alpha / beta version
 | 
			
		||||
			size_t nexn_nl_pos = first_nl_pos;
 | 
			
		||||
 			while (nexn_nl_pos != std::string::npos && body.size() > nexn_nl_pos + 1) {
 | 
			
		||||
				const auto last_nl_pos = nexn_nl_pos;
 | 
			
		||||
				nexn_nl_pos = body.find_first_of("\n\r", last_nl_pos + 1);
 | 
			
		||||
				std::string line;
 | 
			
		||||
				if (nexn_nl_pos == std::string::npos)
 | 
			
		||||
					line = body.substr(last_nl_pos + 1);
 | 
			
		||||
				else
 | 
			
		||||
					line = body.substr(last_nl_pos + 1, nexn_nl_pos - last_nl_pos - 1);
 | 
			
		||||
 | 
			
		||||
				// alpha
 | 
			
		||||
				if (line.substr(0, 6) == "alpha=") {
 | 
			
		||||
					version = line.substr(6);
 | 
			
		||||
					if (!Semver::parse(version)) {
 | 
			
		||||
						BOOST_LOG_TRIVIAL(warning) << format("Received invalid contents for alpha release from `%1%`: Not a correct semver: `%2%`", SLIC3R_APP_NAME, version);
 | 
			
		||||
						return;
 | 
			
		||||
					}
 | 
			
		||||
					BOOST_LOG_TRIVIAL(info) << format("Got %1% online version of alpha release: `%2%`. Sending to GUI thread...", SLIC3R_APP_NAME, version);
 | 
			
		||||
					wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_ALPHA_VERSION_ONLINE);
 | 
			
		||||
					evt->SetString(GUI::from_u8(version));
 | 
			
		||||
					GUI::wxGetApp().QueueEvent(evt);
 | 
			
		||||
 | 
			
		||||
				// beta
 | 
			
		||||
				} else if (line.substr(0, 5) == "beta=") {
 | 
			
		||||
					version = line.substr(5);
 | 
			
		||||
					if (!Semver::parse(version)) {
 | 
			
		||||
						BOOST_LOG_TRIVIAL(warning) << format("Received invalid contents for beta release from `%1%`: Not a correct semver: `%2%`", SLIC3R_APP_NAME, version);
 | 
			
		||||
						return;
 | 
			
		||||
					}
 | 
			
		||||
					BOOST_LOG_TRIVIAL(info) << format("Got %1% online version of beta release: `%2%`. Sending to GUI thread...", SLIC3R_APP_NAME, version);
 | 
			
		||||
					wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_BETA_VERSION_ONLINE);
 | 
			
		||||
					evt->SetString(GUI::from_u8(version));
 | 
			
		||||
					GUI::wxGetApp().QueueEvent(evt);
 | 
			
		||||
				}
 | 
			
		||||
		// beta
 | 
			
		||||
		}
 | 
			
		||||
		else if (line.substr(0, 5) == "beta=") {
 | 
			
		||||
			version = line.substr(5);
 | 
			
		||||
			if (!Semver::parse(version)) {
 | 
			
		||||
				BOOST_LOG_TRIVIAL(warning) << format("Received invalid contents for beta release from `%1%`: Not a correct semver: `%2%`", SLIC3R_APP_NAME, version);
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
		.perform_sync();
 | 
			
		||||
			BOOST_LOG_TRIVIAL(info) << format("Got %1% online version of beta release: `%2%`. Sending to GUI thread...", SLIC3R_APP_NAME, version);
 | 
			
		||||
			wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_BETA_VERSION_ONLINE);
 | 
			
		||||
			evt->SetString(GUI::from_u8(version));
 | 
			
		||||
			GUI::wxGetApp().QueueEvent(evt);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Download vendor indices. Also download new bundles if an index indicates there's a new one available.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue