2018-04-24 18:06:42 +02:00
#include "UpdateDialogs.hpp"
2019-05-13 18:38:48 +02:00
#include <cstring>
#include <boost/format.hpp>
2019-05-14 13:11:55 +02:00
#include <boost/algorithm/string/predicate.hpp>
2019-05-13 18:38:48 +02:00
2018-04-24 18:06:42 +02:00
#include <wx/settings.h>
#include <wx/sizer.h>
#include <wx/event.h>
#include <wx/stattext.h>
#include <wx/button.h>
#include <wx/hyperlink.h>
#include <wx/statbmp.h>
#include <wx/checkbox.h>
#include "libslic3r/libslic3r.h"
#include "libslic3r/Utils.hpp"
#include "GUI.hpp"
2019-02-21 18:59:21 +01:00
#include "GUI_App.hpp"
2018-11-26 14:41:58 +01:00
#include "I18N.hpp"
2018-04-27 12:29:18 +02:00
#include "ConfigWizard.hpp"
2019-04-05 18:53:02 +02:00
#include "wxExtensions.hpp"
2018-04-24 18:06:42 +02:00
namespace Slic3r {
namespace GUI {
2019-05-20 15:32:43 +02:00
static const char * URL_CHANGELOG = "http://files.prusa3d.com/?latest=slicer-stable&lng=%1%" ;
2019-05-13 18:38:48 +02:00
static const char * URL_DOWNLOAD = "https://www.prusa3d.com/downloads&lng=%1%" ;
static const char * URL_DEV = "https://github.com/prusa3d/PrusaSlicer/releases/tag/version_%1%" ;
static const std :: string CONFIG_UPDATE_WIKI_URL ( "https://github.com/prusa3d/PrusaSlicer/wiki/Slic3r-PE-1.40-configuration-update" );
2018-04-27 15:44:32 +02:00
2018-04-24 18:06:42 +02:00
// MsgUpdateSlic3r
2019-09-06 14:48:31 +02:00
MsgUpdateSlic3r :: MsgUpdateSlic3r ( const Semver & ver_current , const Semver & ver_online )
: MsgDialog ( nullptr , _ ( L ( "Update available" )), wxString :: Format ( _ ( L ( "New version of %s is available" )), SLIC3R_APP_NAME ))
2018-04-24 18:06:42 +02:00
{
2019-05-20 18:36:11 +02:00
const bool dev_version = ver_online . prerelease () != nullptr ;
2018-04-24 18:06:42 +02:00
auto * versions = new wxFlexGridSizer ( 2 , 0 , VERT_SPACING );
versions -> Add ( new wxStaticText ( this , wxID_ANY , _ ( L ( "Current version:" ))));
versions -> Add ( new wxStaticText ( this , wxID_ANY , ver_current . to_string ()));
versions -> Add ( new wxStaticText ( this , wxID_ANY , _ ( L ( "New version:" ))));
versions -> Add ( new wxStaticText ( this , wxID_ANY , ver_online . to_string ()));
content_sizer -> Add ( versions );
content_sizer -> AddSpacer ( VERT_SPACING );
2019-05-13 18:38:48 +02:00
if ( dev_version ) {
const std :: string url = ( boost :: format ( URL_DEV ) % ver_online . to_string ()). str ();
const wxString url_wx = from_u8 ( url );
auto * link = new wxHyperlinkCtrl ( this , wxID_ANY , _ ( L ( "Changelog && Download" )), url_wx );
content_sizer -> Add ( link );
} else {
2019-07-29 17:55:50 +02:00
const auto lang_code = wxGetApp (). current_language_code_safe (). ToStdString ();
2019-05-13 18:38:48 +02:00
const std :: string url_log = ( boost :: format ( URL_CHANGELOG ) % lang_code ). str ();
const wxString url_log_wx = from_u8 ( url_log );
auto * link_log = new wxHyperlinkCtrl ( this , wxID_ANY , _ ( L ( "Open changelog page" )), url_log_wx );
content_sizer -> Add ( link_log );
const std :: string url_dw = ( boost :: format ( URL_DOWNLOAD ) % lang_code ). str ();
const wxString url_dw_wx = from_u8 ( url_dw );
auto * link_dw = new wxHyperlinkCtrl ( this , wxID_ANY , _ ( L ( "Open download page" )), url_dw_wx );
content_sizer -> Add ( link_dw );
}
2018-04-24 18:06:42 +02:00
content_sizer -> AddSpacer ( 2 * VERT_SPACING );
cbox = new wxCheckBox ( this , wxID_ANY , _ ( L ( "Don't notify about new releases any more" )));
content_sizer -> Add ( cbox );
content_sizer -> AddSpacer ( VERT_SPACING );
Fit ();
}
MsgUpdateSlic3r ::~ MsgUpdateSlic3r () {}
bool MsgUpdateSlic3r :: disable_version_check () const
{
return cbox -> GetValue ();
}
// MsgUpdateConfig
2019-05-13 18:38:48 +02:00
MsgUpdateConfig :: MsgUpdateConfig ( const std :: vector < Update > & updates ) :
2018-04-30 14:31:57 +02:00
MsgDialog ( nullptr , _ ( L ( "Configuration update" )), _ ( L ( "Configuration update is available" )), wxID_NONE )
2018-04-24 18:06:42 +02:00
{
auto * text = new wxStaticText ( this , wxID_ANY , _ ( L (
"Would you like to install it? \n\n "
"Note that a full configuration snapshot will be created first. It can then be restored at any time "
"should there be a problem with the new version. \n\n "
"Updated configuration bundles:"
)));
2019-02-21 18:59:21 +01:00
text -> Wrap ( CONTENT_WIDTH * wxGetApp (). em_unit ());
2018-04-24 18:06:42 +02:00
content_sizer -> Add ( text );
content_sizer -> AddSpacer ( VERT_SPACING );
2019-07-29 17:55:50 +02:00
const auto lang_code = wxGetApp (). current_language_code_safe (). ToStdString ();
2019-05-13 18:38:48 +02:00
auto * versions = new wxBoxSizer ( wxVERTICAL );
2018-04-24 18:06:42 +02:00
for ( const auto & update : updates ) {
2019-05-13 18:38:48 +02:00
auto * flex = new wxFlexGridSizer ( 2 , 0 , VERT_SPACING );
auto * text_vendor = new wxStaticText ( this , wxID_ANY , update . vendor );
2018-04-24 18:06:42 +02:00
text_vendor -> SetFont ( boldfont );
2019-05-13 18:38:48 +02:00
flex -> Add ( text_vendor );
flex -> Add ( new wxStaticText ( this , wxID_ANY , update . version . to_string ()));
if ( ! update . comment . empty ()) {
flex -> Add ( new wxStaticText ( this , wxID_ANY , _ ( L ( "Comment:" ))), 0 , wxALIGN_RIGHT );
2019-08-26 16:27:51 +02:00
auto * update_comment = new wxStaticText ( this , wxID_ANY , from_u8 ( update . comment ));
update_comment -> Wrap ( CONTENT_WIDTH * wxGetApp (). em_unit ());
flex -> Add ( update_comment );
2019-05-13 18:38:48 +02:00
}
versions -> Add ( flex );
2019-05-20 18:36:11 +02:00
if ( ! update . changelog_url . empty () && update . version . prerelease () == nullptr ) {
2019-05-13 18:38:48 +02:00
auto * line = new wxBoxSizer ( wxHORIZONTAL );
auto changelog_url = ( boost :: format ( update . changelog_url ) % lang_code ). str ();
line -> AddSpacer ( 3 * VERT_SPACING );
line -> Add ( new wxHyperlinkCtrl ( this , wxID_ANY , _ ( L ( "Open changelog page" )), changelog_url ));
versions -> Add ( line );
}
2018-04-24 18:06:42 +02:00
}
content_sizer -> Add ( versions );
content_sizer -> AddSpacer ( 2 * VERT_SPACING );
auto * btn_cancel = new wxButton ( this , wxID_CANCEL );
btn_sizer -> Add ( btn_cancel );
btn_sizer -> AddSpacer ( HORIZ_SPACING );
2018-04-25 15:14:01 +02:00
auto * btn_ok = new wxButton ( this , wxID_OK );
2018-04-24 18:06:42 +02:00
btn_sizer -> Add ( btn_ok );
btn_ok -> SetFocus ();
Fit ();
}
MsgUpdateConfig ::~ MsgUpdateConfig () {}
2020-02-04 15:24:35 +01:00
//MsgUpdateForced
MsgUpdateForced :: MsgUpdateForced ( const std :: vector < Update >& updates ) :
2020-02-27 14:11:20 +01:00
MsgDialog ( nullptr , wxString :: Format ( _ ( L ( "%s incompatibility" )), SLIC3R_APP_NAME ), _ ( L ( "You must install a configuration update." )) + " " , wxID_NONE )
2020-02-04 15:24:35 +01:00
{
auto * text = new wxStaticText ( this , wxID_ANY , wxString :: Format ( _ ( L (
"%s will now start updates. Otherwise it won't be able to start. \n\n "
"Note that a full configuration snapshot will be created first. It can then be restored at any time "
"should there be a problem with the new version. \n\n "
"Updated configuration bundles:"
)), SLIC3R_APP_NAME ));
logo -> SetBitmap ( create_scaled_bitmap ( "PrusaSlicer_192px_grayscale.png" , this , 192 ));
text -> Wrap ( CONTENT_WIDTH * wxGetApp (). em_unit ());
content_sizer -> Add ( text );
content_sizer -> AddSpacer ( VERT_SPACING );
const auto lang_code = wxGetApp (). current_language_code_safe (). ToStdString ();
2020-02-06 11:32:45 +01:00
auto * versions = new wxFlexGridSizer ( 2 , 0 , VERT_SPACING );
2020-02-04 15:24:35 +01:00
for ( const auto & update : updates ) {
auto * text_vendor = new wxStaticText ( this , wxID_ANY , update . vendor );
text_vendor -> SetFont ( boldfont );
2020-02-06 11:32:45 +01:00
versions -> Add ( text_vendor );
versions -> Add ( new wxStaticText ( this , wxID_ANY , update . version . to_string ()));
2020-02-04 15:24:35 +01:00
if ( ! update . comment . empty ()) {
2020-02-06 11:32:45 +01:00
versions -> Add ( new wxStaticText ( this , wxID_ANY , _ ( L ( "Comment:" ))) /*, 0, wxALIGN_RIGHT*/ ); //uncoment if align to right (might not look good if 1 vedor name is longer than other names)
2020-02-04 15:24:35 +01:00
auto * update_comment = new wxStaticText ( this , wxID_ANY , from_u8 ( update . comment ));
update_comment -> Wrap ( CONTENT_WIDTH * wxGetApp (). em_unit ());
2020-02-06 11:32:45 +01:00
versions -> Add ( update_comment );
2020-02-04 15:24:35 +01:00
}
if ( ! update . changelog_url . empty () && update . version . prerelease () == nullptr ) {
auto * line = new wxBoxSizer ( wxHORIZONTAL );
auto changelog_url = ( boost :: format ( update . changelog_url ) % lang_code ). str ();
line -> AddSpacer ( 3 * VERT_SPACING );
line -> Add ( new wxHyperlinkCtrl ( this , wxID_ANY , _ ( L ( "Open changelog page" )), changelog_url ));
versions -> Add ( line );
}
}
content_sizer -> Add ( versions );
content_sizer -> AddSpacer ( 2 * VERT_SPACING );
auto * btn_exit = new wxButton ( this , wxID_EXIT , wxString :: Format ( _ ( L ( "Exit %s" )), SLIC3R_APP_NAME ));
btn_sizer -> Add ( btn_exit );
btn_sizer -> AddSpacer ( HORIZ_SPACING );
auto * btn_ok = new wxButton ( this , wxID_OK );
btn_sizer -> Add ( btn_ok );
btn_ok -> SetFocus ();
auto exiter = [ this ]( const wxCommandEvent & evt ) { this -> EndModal ( evt . GetId ()); };
btn_exit -> Bind ( wxEVT_BUTTON , exiter );
btn_ok -> Bind ( wxEVT_BUTTON , exiter );
Fit ();
}
MsgUpdateForced ::~ MsgUpdateForced () {}
2018-04-24 18:06:42 +02:00
// MsgDataIncompatible
2018-04-24 18:40:06 +02:00
MsgDataIncompatible :: MsgDataIncompatible ( const std :: unordered_map < std :: string , wxString > & incompats ) :
2019-04-26 10:52:38 +02:00
MsgDialog ( nullptr , wxString :: Format ( _ ( L ( "%s incompatibility" )), SLIC3R_APP_NAME ),
wxString :: Format ( _ ( L ( "%s configuration is incompatible" )), SLIC3R_APP_NAME ), wxID_NONE )
2018-04-24 18:06:42 +02:00
{
2020-01-31 16:50:11 +01:00
logo -> SetBitmap ( create_scaled_bitmap ( "PrusaSlicer_192px_grayscale.png" , this , 192 ));
2019-04-05 18:53:02 +02:00
2019-04-15 16:14:19 +02:00
auto * text = new wxStaticText ( this , wxID_ANY , wxString :: Format ( _ ( L (
"This version of %s is not compatible with currently installed configuration bundles. \n "
"This probably happened as a result of running an older %s after using a newer one. \n\n "
2018-04-24 18:29:36 +02:00
2019-04-26 10:52:38 +02:00
"You may either exit %s and try again with a newer version, or you may re-run the initial configuration. "
2019-12-04 11:12:28 +01:00
"Doing so will create a backup snapshot of the existing configuration before installing files compatible with this %s." )) + " \n " ,
2020-02-04 15:24:35 +01:00
SLIC3R_APP_NAME , SLIC3R_APP_NAME , SLIC3R_APP_NAME , SLIC3R_APP_NAME ));
2019-02-21 18:59:21 +01:00
text -> Wrap ( CONTENT_WIDTH * wxGetApp (). em_unit ());
2018-04-24 18:06:42 +02:00
content_sizer -> Add ( text );
2019-04-15 16:14:19 +02:00
auto * text2 = new wxStaticText ( this , wxID_ANY , wxString :: Format ( _ ( L ( "This %s version: %s" )), SLIC3R_APP_NAME , SLIC3R_VERSION ));
2019-02-21 18:59:21 +01:00
text2 -> Wrap ( CONTENT_WIDTH * wxGetApp (). em_unit ());
2018-04-24 18:06:42 +02:00
content_sizer -> Add ( text2 );
content_sizer -> AddSpacer ( VERT_SPACING );
auto * text3 = new wxStaticText ( this , wxID_ANY , _ ( L ( "Incompatible bundles:" )));
2019-02-21 18:59:21 +01:00
text3 -> Wrap ( CONTENT_WIDTH * wxGetApp (). em_unit ());
2018-04-24 18:06:42 +02:00
content_sizer -> Add ( text3 );
content_sizer -> AddSpacer ( VERT_SPACING );
auto * versions = new wxFlexGridSizer ( 2 , 0 , VERT_SPACING );
for ( const auto & incompat : incompats ) {
auto * text_vendor = new wxStaticText ( this , wxID_ANY , incompat . first );
text_vendor -> SetFont ( boldfont );
versions -> Add ( text_vendor );
versions -> Add ( new wxStaticText ( this , wxID_ANY , incompat . second ));
}
content_sizer -> Add ( versions );
content_sizer -> AddSpacer ( 2 * VERT_SPACING );
2019-04-26 10:52:38 +02:00
auto * btn_exit = new wxButton ( this , wxID_EXIT , wxString :: Format ( _ ( L ( "Exit %s" )), SLIC3R_APP_NAME ));
2018-04-24 18:06:42 +02:00
btn_sizer -> Add ( btn_exit );
btn_sizer -> AddSpacer ( HORIZ_SPACING );
auto * btn_reconf = new wxButton ( this , wxID_REPLACE , _ ( L ( "Re-configure" )));
btn_sizer -> Add ( btn_reconf );
btn_exit -> SetFocus ();
auto exiter = [ this ]( const wxCommandEvent & evt ) { this -> EndModal ( evt . GetId ()); };
btn_exit -> Bind ( wxEVT_BUTTON , exiter );
btn_reconf -> Bind ( wxEVT_BUTTON , exiter );
Fit ();
}
MsgDataIncompatible ::~ MsgDataIncompatible () {}
2018-04-27 12:29:18 +02:00
// MsgDataLegacy
MsgDataLegacy :: MsgDataLegacy () :
2018-04-30 14:31:57 +02:00
MsgDialog ( nullptr , _ ( L ( "Configuration update" )), _ ( L ( "Configuration update" )))
2018-04-27 12:29:18 +02:00
{
auto * text = new wxStaticText ( this , wxID_ANY , wxString :: Format (
_ ( L (
2019-04-15 16:14:19 +02:00
"%s now uses an updated configuration structure. \n\n "
2018-04-27 12:29:18 +02:00
"So called 'System presets' have been introduced, which hold the built-in default settings for various "
"printers. These System presets cannot be modified, instead, users now may create their "
"own presets inheriting settings from one of the System presets. \n "
"An inheriting preset may either inherit a particular value from its parent or override it with a customized value. \n\n "
"Please proceed with the %s that follows to set up the new presets "
"and to choose whether to enable automatic preset updates."
)),
2020-02-24 10:54:50 +01:00
SLIC3R_APP_NAME , _ ( ConfigWizard :: name ())
2018-04-27 12:29:18 +02:00
));
2019-02-21 18:59:21 +01:00
text -> Wrap ( CONTENT_WIDTH * wxGetApp (). em_unit ());
2018-04-27 12:29:18 +02:00
content_sizer -> Add ( text );
content_sizer -> AddSpacer ( VERT_SPACING );
2018-04-27 15:44:32 +02:00
auto * text2 = new wxStaticText ( this , wxID_ANY , _ ( L ( "For more information please visit our wiki page:" )));
2019-05-14 19:46:01 +02:00
static const wxString url ( "https://github.com/prusa3d/PrusaSlicer/wiki/Slic3r-PE-1.40-configuration-update" );
2018-04-27 15:44:32 +02:00
// The wiki page name is intentionally not localized:
2019-04-26 10:52:38 +02:00
auto * link = new wxHyperlinkCtrl ( this , wxID_ANY , wxString :: Format ( "%s 1.40 configuration update" , SLIC3R_APP_NAME ), CONFIG_UPDATE_WIKI_URL );
2018-04-27 15:44:32 +02:00
content_sizer -> Add ( text2 );
content_sizer -> Add ( link );
content_sizer -> AddSpacer ( VERT_SPACING );
2018-04-27 12:29:18 +02:00
Fit ();
}
MsgDataLegacy ::~ MsgDataLegacy () {}
2020-02-04 15:24:35 +01:00
// MsgNoUpdate
MsgNoUpdates :: MsgNoUpdates () :
2020-02-24 10:54:50 +01:00
MsgDialog ( nullptr , _ ( L ( "Configuration updates" )), _ ( L ( "No updates available" )))
2020-02-04 15:24:35 +01:00
{
auto * text = new wxStaticText ( this , wxID_ANY , wxString :: Format (
_ ( L (
2020-02-24 10:54:50 +01:00
"%s has no configuration updates available."
2020-02-04 15:24:35 +01:00
)),
2020-02-24 10:54:50 +01:00
SLIC3R_APP_NAME
2020-02-04 15:24:35 +01:00
));
text -> Wrap ( CONTENT_WIDTH * wxGetApp (). em_unit ());
content_sizer -> Add ( text );
content_sizer -> AddSpacer ( VERT_SPACING );
logo -> SetBitmap ( create_scaled_bitmap ( "PrusaSlicer_192px_grayscale.png" , this , 192 ));
Fit ();
}
MsgNoUpdates ::~ MsgNoUpdates () {}
2018-04-24 18:06:42 +02:00
}
}