SPE-1970: Notify about available config update after sync.

Notification about conf update with new printer mockup.
"new printer" information in the update dialogs.
This commit is contained in:
David Kocik 2023-10-19 11:15:18 +02:00
parent 5862e85c57
commit 78e128de1c
8 changed files with 92 additions and 13 deletions

View File

@ -2330,6 +2330,15 @@ namespace PresetUtils {
}
return true;
}
bool compare_vendor_profile_printers(const VendorProfile& vp_old, const VendorProfile& vp_new, std::vector<std::string>& new_printers)
{
for (const VendorProfile::PrinterModel& model : vp_new.models)
{
if (std::find_if(vp_old.models.begin(), vp_old.models.end(), [model](const VendorProfile::PrinterModel& pm) { return pm.id == model.id; }) == vp_old.models.end())
new_printers.push_back(model.name);
}
return new_printers.empty();
}
} // namespace PresetUtils
} // namespace Slic3r

View File

@ -630,9 +630,10 @@ namespace PresetUtils {
std::string system_printer_bed_model(const Preset& preset);
std::string system_printer_bed_texture(const Preset& preset);
bool vendor_profile_has_all_resources(const VendorProfile& vp);
bool compare_vendor_profile_printers(const VendorProfile& vp_old, const VendorProfile& vp_new, std::vector<std::string>& new_printers);
} // namespace PresetUtils
//////////////////////////////////////////////////////////////////////
class PhysicalPrinter

View File

@ -825,13 +825,16 @@ void GUI_App::post_init()
// This is ugly but I honestly found no better way to do it.
// Neither wxShowEvent nor wxWindowCreateEvent work reliably.
if (this->preset_updater) { // G-Code Viewer does not initialize preset_updater.
#if 0 // This code was moved to EVT_CONFIG_UPDATER_SYNC_DONE bind - after preset_updater finishes synchronization.
if (! this->check_updates(false))
// Configuration is not compatible and reconfigure was refused by the user. Application is closing.
return;
#endif
CallAfter([this] {
// preset_updater->sync downloads profile updates on background so it must begin after config wizard finished.
bool cw_showed = this->config_wizard_startup();
this->preset_updater->sync(preset_bundle);
this->preset_updater->sync(preset_bundle, this);
if (! cw_showed) {
// The CallAfter is needed as well, without it, GL extensions did not show.
// Also, we only want to show this when the wizard does not, so the new user
@ -1295,6 +1298,10 @@ bool GUI_App::on_init_inner()
show_error(nullptr, evt.GetString());
});
Bind(EVT_CONFIG_UPDATER_SYNC_DONE, [this](const wxCommandEvent& evt) {
this->check_updates(false);
});
}
else {
#ifdef __WXMSW__

View File

@ -64,6 +64,7 @@ enum class NotificationType
// Notification on the start of PrusaSlicer, when updates of system profiles are detected.
// Contains a hyperlink to execute installation of the new system profiles.
PresetUpdateAvailable,
PresetUpdateAvailableNewPrinter,
// LoadingFailed,
// Errors emmited by Print::validate
// difference from Slicing error is that they disappear not grey out at update_background_process
@ -908,6 +909,13 @@ private:
return true;
}
},
{NotificationType::PresetUpdateAvailableNewPrinter, NotificationLevel::ImportantNotificationLevel, 20, _u8L("Configuration update is available. Update contains new printer releases."), _u8L("See more."),
[](wxEvtHandler* evnthndlr) {
if (evnthndlr != nullptr)
wxPostEvent(evnthndlr, PresetUpdateAvailableClickedEvent(EVT_PRESET_UPDATE_AVAILABLE_CLICKED));
return true;
}
},
{NotificationType::EmptyColorChangeCode, NotificationLevel::PrintInfoNotificationLevel, 10,
_u8L("You have just added a G-code for color change, but its value is empty.\n"
"To export the G-code correctly, check the \"Color Change G-code\" in \"Printer Settings > Custom G-code\"") },

View File

@ -305,6 +305,13 @@ MsgUpdateConfig::MsgUpdateConfig(const std::vector<Update> &updates, bool force_
flex->Add(update_comment);
}
if (! update.new_printers.empty()) {
flex->Add(new wxStaticText(this, wxID_ANY, _L_PLURAL("New printer:", "New printers:", update.new_printers.find(',') == std::string::npos ? 1 : 2)), 0, wxALIGN_RIGHT);
auto* update_printer = new wxStaticText(this, wxID_ANY, from_u8(update.new_printers));
update_printer->Wrap(CONTENT_WIDTH * wxGetApp().em_unit());
flex->Add(update_printer);
}
versions->Add(flex);
if (! update.changelog_url.empty() && update.version.prerelease() == nullptr) {
@ -365,6 +372,13 @@ MsgUpdateForced::MsgUpdateForced(const std::vector<Update>& updates) :
versions->Add(update_comment);
}
if (!update.new_printers.empty()) {
versions->Add(new wxStaticText(this, wxID_ANY, _L_PLURAL("New printer:", "New printers:", update.new_printers.find(',') == std::string::npos ? 1 : 2))/*, 0, wxALIGN_RIGHT*/);
auto* update_printer = new wxStaticText(this, wxID_ANY, from_u8(update.new_printers));
update_printer->Wrap(CONTENT_WIDTH * wxGetApp().em_unit());
versions->Add(update_printer);
}
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();

View File

@ -90,12 +90,14 @@ public:
Semver version;
std::string comment;
std::string changelog_url;
std::string new_printers;
Update(std::string vendor, Semver version, std::string comment, std::string changelog_url)
Update(std::string vendor, Semver version, std::string comment, std::string changelog_url, std::string new_printers)
: vendor(std::move(vendor))
, version(std::move(version))
, comment(std::move(comment))
, changelog_url(std::move(changelog_url))
, new_printers(std::move(new_printers))
{}
};
@ -118,12 +120,14 @@ public:
Semver version;
std::string comment;
std::string changelog_url;
std::string new_printers;
Update(std::string vendor, Semver version, std::string comment, std::string changelog_url)
Update(std::string vendor, Semver version, std::string comment, std::string changelog_url, std::string new_printers)
: vendor(std::move(vendor))
, version(std::move(version))
, comment(std::move(comment))
, changelog_url(std::move(changelog_url))
, new_printers(std::move(new_printers))
{}
};

View File

@ -89,6 +89,9 @@ std::string escape_string_url(const std::string& unescaped)
return ret_val;
}
}
wxDEFINE_EVENT(EVT_CONFIG_UPDATER_SYNC_DONE, wxCommandEvent);
struct Update
{
fs::path source;
@ -99,15 +102,17 @@ struct Update
std::string changelog_url;
bool forced_update;
std::vector<std::string> new_printers;
Update() {}
Update(fs::path &&source, fs::path &&target, const Version &version, std::string vendor, std::string changelog_url, bool forced = false)
Update(fs::path &&source, fs::path &&target, const Version &version, std::string vendor, std::string changelog_url, bool forced = false, std::vector<std::string> new_printers = {})
: source(std::move(source))
, target(std::move(target))
, version(version)
, vendor(std::move(vendor))
, changelog_url(std::move(changelog_url))
, forced_update(forced)
, new_printers(std::move(new_printers))
{}
void install() const
@ -900,13 +905,16 @@ Updates PresetUpdater::priv::get_config_updates(const Semver &old_slic3r_version
if (fs::exists(path_in_cache)) {
try {
VendorProfile new_vp = VendorProfile::from_ini(path_in_cache, true);
VendorProfile old_vp = VendorProfile::from_ini(bundle_path, true);
if (new_vp.config_version == recommended->config_version) {
// The config bundle from the cache directory matches the recommended version of the index from the cache directory.
// This is the newest known recommended config. Use it.
if (!PresetUtils::vendor_profile_has_all_resources(new_vp)) {
BOOST_LOG_TRIVIAL(warning) << "Some resources are missing for update of vedor " << new_vp.id;
}
new_update = Update(std::move(path_in_cache), std::move(bundle_path), *recommended, vp.name, vp.changelog_url, current_not_supported);
std::vector<std::string> new_printers;
PresetUtils::compare_vendor_profile_printers(old_vp, new_vp, new_printers);
new_update = Update(std::move(path_in_cache), std::move(bundle_path), *recommended, vp.name, vp.changelog_url, current_not_supported, std::move(new_printers));
// and install the config index from the cache into vendor's directory.
bundle_path_idx_to_install = idx.path();
found = true;
@ -1120,7 +1128,7 @@ PresetUpdater::~PresetUpdater()
}
}
void PresetUpdater::sync(const PresetBundle *preset_bundle)
void PresetUpdater::sync(const PresetBundle *preset_bundle, wxEvtHandler* evt_handler)
{
p->set_download_prefs(GUI::wxGetApp().app_config);
if (!p->enabled_version_check && !p->enabled_config_update) { return; }
@ -1131,9 +1139,11 @@ void PresetUpdater::sync(const PresetBundle *preset_bundle)
VendorMap vendors = preset_bundle->vendors;
std::string index_archive_url = GUI::wxGetApp().app_config->index_archive_url();
p->thread = std::thread([this, vendors, index_archive_url]() {
p->thread = std::thread([this, vendors, index_archive_url, evt_handler]() {
this->p->prune_tmps();
this->p->sync_config(std::move(vendors), index_archive_url);
wxCommandEvent* evt = new wxCommandEvent(EVT_CONFIG_UPDATER_SYNC_DONE);
evt_handler->QueueEvent(evt);
});
}
@ -1252,7 +1262,13 @@ PresetUpdater::UpdateResult PresetUpdater::config_update(const Semver& old_slic3
std::vector<GUI::MsgUpdateForced::Update> updates_msg;
for (const auto& update : updates.updates) {
std::string changelog_url = update.version.config_version.prerelease() == nullptr ? update.changelog_url : std::string();
updates_msg.emplace_back(update.vendor, update.version.config_version, update.version.comment, std::move(changelog_url));
std::string printers;
for (size_t i = 0; i < update.new_printers.size(); i++) {
if (i > 0)
printers += ", ";
printers += update.new_printers[i];
}
updates_msg.emplace_back(update.vendor, update.version.config_version, update.version.comment, std::move(changelog_url), std::move(printers));
}
GUI::MsgUpdateForced dlg(updates_msg);
@ -1274,7 +1290,14 @@ PresetUpdater::UpdateResult PresetUpdater::config_update(const Semver& old_slic3
// regular update
if (params == UpdateParams::SHOW_NOTIFICATION) {
p->set_waiting_updates(updates);
GUI::wxGetApp().plater()->get_notification_manager()->push_notification(GUI::NotificationType::PresetUpdateAvailable);
bool new_printer = false;
for (const Update& updt : updates.updates) {
if(updt.new_printers.size() > 0) {
new_printer = true;
break;
}
}
GUI::wxGetApp().plater()->get_notification_manager()->push_notification(new_printer? GUI::NotificationType::PresetUpdateAvailableNewPrinter : GUI::NotificationType::PresetUpdateAvailable);
}
else {
BOOST_LOG_TRIVIAL(info) << format("Update of %1% bundles available. Asking for confirmation ...", p->waiting_updates.updates.size());
@ -1282,7 +1305,13 @@ PresetUpdater::UpdateResult PresetUpdater::config_update(const Semver& old_slic3
std::vector<GUI::MsgUpdateConfig::Update> updates_msg;
for (const auto& update : updates.updates) {
std::string changelog_url = update.version.config_version.prerelease() == nullptr ? update.changelog_url : std::string();
updates_msg.emplace_back(update.vendor, update.version.config_version, update.version.comment, std::move(changelog_url));
std::string printers;
for (size_t i = 0; i < update.new_printers.size(); i++) {
if (i > 0)
printers += ", ";
printers += update.new_printers[i];
}
updates_msg.emplace_back(update.vendor, update.version.config_version, update.version.comment, std::move(changelog_url), std::move(printers));
}
GUI::MsgUpdateConfig dlg(updates_msg, params == UpdateParams::FORCED_BEFORE_WIZARD);
@ -1426,7 +1455,13 @@ void PresetUpdater::on_update_notification_confirm()
std::vector<GUI::MsgUpdateConfig::Update> updates_msg;
for (const auto& update : p->waiting_updates.updates) {
std::string changelog_url = update.version.config_version.prerelease() == nullptr ? update.changelog_url : std::string();
updates_msg.emplace_back(update.vendor, update.version.config_version, update.version.comment, std::move(changelog_url));
std::string printers;
for (size_t i = 0; i < update.new_printers.size(); i++) {
if (i > 0)
printers += ", ";
printers += update.new_printers[i];
}
updates_msg.emplace_back(update.vendor, update.version.config_version, update.version.comment, std::move(changelog_url), std::move(printers));
}
GUI::MsgUpdateConfig dlg(updates_msg);

View File

@ -30,7 +30,7 @@ public:
~PresetUpdater();
// If either version check or config updating is enabled, get the appropriate data in the background and cache it.
void sync(const PresetBundle *preset_bundle);
void sync(const PresetBundle *preset_bundle, wxEvtHandler* evt_handler);
void cancel_sync();
// If version check is enabled, check if chaced online slic3r version is newer, notify if so.
@ -74,5 +74,6 @@ private:
//wxDECLARE_EVENT(EVT_SLIC3R_VERSION_ONLINE, wxCommandEvent);
//wxDECLARE_EVENT(EVT_SLIC3R_EXPERIMENTAL_VERSION_ONLINE, wxCommandEvent);
wxDECLARE_EVENT(EVT_CONFIG_UPDATER_SYNC_DONE, wxCommandEvent);
}
#endif