Unsaved Changes : improvement for the GUI_App::check_unsaved_changes()
Added use of UnsavedChangesDialog
This commit is contained in:
parent
8f15efbf9a
commit
618f04717f
8 changed files with 228 additions and 98 deletions
|
@ -327,6 +327,32 @@ const std::string& PresetBundle::get_preset_name_by_alias( const Preset::Type& p
|
||||||
return presets.get_preset_name_by_alias(alias);
|
return presets.get_preset_name_by_alias(alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PresetBundle::save_changes_for_preset(const std::string& new_name, Preset::Type type,
|
||||||
|
const std::vector<std::string>& unselected_options)
|
||||||
|
{
|
||||||
|
PresetCollection& presets = type == Preset::TYPE_PRINT ? prints :
|
||||||
|
type == Preset::TYPE_SLA_PRINT ? sla_prints :
|
||||||
|
type == Preset::TYPE_FILAMENT ? filaments :
|
||||||
|
type == Preset::TYPE_SLA_MATERIAL ? sla_materials : printers;
|
||||||
|
|
||||||
|
// if we want to save just some from selected options
|
||||||
|
if (!unselected_options.empty()) {
|
||||||
|
// revert unselected options to the old values
|
||||||
|
presets.get_edited_preset().config.apply_only(presets.get_selected_preset().config, unselected_options);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the preset into Slic3r::data_dir / presets / section_name / preset_name.ini
|
||||||
|
presets.save_current_preset(new_name);
|
||||||
|
// Mark the print & filament enabled if they are compatible with the currently selected preset.
|
||||||
|
// If saving the preset changes compatibility with other presets, keep the now incompatible dependent presets selected, however with a "red flag" icon showing that they are no more compatible.
|
||||||
|
update_compatible(PresetSelectCompatibleType::Never);
|
||||||
|
|
||||||
|
if (type == Preset::TYPE_FILAMENT) {
|
||||||
|
// synchronize the first filament presets.
|
||||||
|
set_filament_preset(0, filaments.get_selected_preset_name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PresetBundle::load_installed_filaments(AppConfig &config)
|
void PresetBundle::load_installed_filaments(AppConfig &config)
|
||||||
{
|
{
|
||||||
if (! config.has_section(AppConfig::SECTION_FILAMENTS)) {
|
if (! config.has_section(AppConfig::SECTION_FILAMENTS)) {
|
||||||
|
|
|
@ -130,6 +130,10 @@ public:
|
||||||
|
|
||||||
const std::string& get_preset_name_by_alias(const Preset::Type& preset_type, const std::string& alias) const;
|
const std::string& get_preset_name_by_alias(const Preset::Type& preset_type, const std::string& alias) const;
|
||||||
|
|
||||||
|
// Save current preset of a required type under a new name. If the name is different from the old one,
|
||||||
|
// Unselected option would be reverted to the beginning values
|
||||||
|
void save_changes_for_preset(const std::string& new_name, Preset::Type type, const std::vector<std::string>& unselected_options);
|
||||||
|
|
||||||
static const char *PRUSA_BUNDLE;
|
static const char *PRUSA_BUNDLE;
|
||||||
private:
|
private:
|
||||||
std::string load_system_presets();
|
std::string load_system_presets();
|
||||||
|
|
|
@ -57,6 +57,8 @@
|
||||||
#include "RemovableDriveManager.hpp"
|
#include "RemovableDriveManager.hpp"
|
||||||
#include "InstanceCheck.hpp"
|
#include "InstanceCheck.hpp"
|
||||||
#include "NotificationManager.hpp"
|
#include "NotificationManager.hpp"
|
||||||
|
#include "UnsavedChangesDialog.hpp"
|
||||||
|
#include "PresetComboBoxes.hpp"
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
#include <dbt.h>
|
#include <dbt.h>
|
||||||
|
@ -1157,29 +1159,66 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
|
||||||
// to notify the user whether he is aware that some preset changes will be lost.
|
// to notify the user whether he is aware that some preset changes will be lost.
|
||||||
bool GUI_App::check_unsaved_changes(const wxString &header)
|
bool GUI_App::check_unsaved_changes(const wxString &header)
|
||||||
{
|
{
|
||||||
wxString dirty;
|
|
||||||
PrinterTechnology printer_technology = preset_bundle->printers.get_edited_preset().printer_technology();
|
PrinterTechnology printer_technology = preset_bundle->printers.get_edited_preset().printer_technology();
|
||||||
for (Tab *tab : tabs_list)
|
|
||||||
|
bool has_unsaved_changes = false;
|
||||||
|
for (Tab* tab : tabs_list)
|
||||||
if (tab->supports_printer_technology(printer_technology) && tab->current_preset_is_dirty()) {
|
if (tab->supports_printer_technology(printer_technology) && tab->current_preset_is_dirty()) {
|
||||||
if (dirty.empty())
|
has_unsaved_changes = true;
|
||||||
dirty = tab->title();
|
break;
|
||||||
else
|
|
||||||
dirty += wxString(", ") + tab->title();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dirty.empty())
|
if (has_unsaved_changes)
|
||||||
// No changes, the application may close or reload presets.
|
{
|
||||||
return true;
|
UnsavedChangesDialog dlg(header);
|
||||||
// Ask the user.
|
if (dlg.ShowModal() == wxID_CANCEL)
|
||||||
wxString message;
|
return false;
|
||||||
if (! header.empty())
|
|
||||||
message = header + "\n\n";
|
if (dlg.save_preset()) // save selected changes
|
||||||
message += _(L("The presets on the following tabs were modified")) + ": " + dirty + "\n\n" + _(L("Discard changes and continue anyway?"));
|
{
|
||||||
wxMessageDialog dialog(mainframe,
|
struct NameType
|
||||||
message,
|
{
|
||||||
wxString(SLIC3R_APP_NAME) + " - " + _(L("Unsaved Presets")),
|
std::string name;
|
||||||
wxICON_QUESTION | wxYES_NO | wxNO_DEFAULT);
|
Preset::Type type {Preset::TYPE_INVALID};
|
||||||
return dialog.ShowModal() == wxID_YES;
|
};
|
||||||
|
|
||||||
|
std::vector<NameType> names_and_types;
|
||||||
|
|
||||||
|
// for system/default/external presets we should take an edited name
|
||||||
|
std::vector<Preset::Type> types;
|
||||||
|
for (Tab* tab : tabs_list)
|
||||||
|
if (tab->supports_printer_technology(printer_technology) && tab->current_preset_is_dirty())
|
||||||
|
{
|
||||||
|
const Preset& preset = tab->get_presets()->get_edited_preset();
|
||||||
|
if (preset.is_system || preset.is_default || preset.is_external)
|
||||||
|
types.emplace_back(preset.type);
|
||||||
|
|
||||||
|
names_and_types.emplace_back(NameType{ preset.name, preset.type });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!types.empty()) {
|
||||||
|
SavePresetDialog save_dlg(types);
|
||||||
|
if (save_dlg.ShowModal() != wxID_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (NameType& nt : names_and_types) {
|
||||||
|
const std::string name = save_dlg.get_name(nt.type);
|
||||||
|
if (!name.empty())
|
||||||
|
nt.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const NameType& nt : names_and_types)
|
||||||
|
preset_bundle->save_changes_for_preset(nt.name, nt.type, dlg.get_unselected_options(nt.type));
|
||||||
|
|
||||||
|
// if we saved changes to the new presets, we should to
|
||||||
|
// synchronize config.ini with the current selections.
|
||||||
|
preset_bundle->export_selections(*app_config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GUI_App::checked_tab(Tab* tab)
|
bool GUI_App::checked_tab(Tab* tab)
|
||||||
|
|
|
@ -1170,8 +1170,26 @@ void SavePresetDialog::Item::accept()
|
||||||
// SavePresetDialog
|
// SavePresetDialog
|
||||||
//-----------------------------------------------
|
//-----------------------------------------------
|
||||||
|
|
||||||
SavePresetDialog::SavePresetDialog(Preset::Type type, const std::string& suffix)
|
SavePresetDialog::SavePresetDialog(Preset::Type type, std::string suffix)
|
||||||
: DPIDialog(nullptr, wxID_ANY, _L("Save preset"), wxDefaultPosition, wxSize(45 * wxGetApp().em_unit(), 5 * wxGetApp().em_unit()), wxDEFAULT_DIALOG_STYLE | wxICON_WARNING | wxRESIZE_BORDER)
|
: DPIDialog(nullptr, wxID_ANY, _L("Save preset"), wxDefaultPosition, wxSize(45 * wxGetApp().em_unit(), 5 * wxGetApp().em_unit()), wxDEFAULT_DIALOG_STYLE | wxICON_WARNING | wxRESIZE_BORDER)
|
||||||
|
{
|
||||||
|
build(std::vector<Preset::Type>{type}, suffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
SavePresetDialog::SavePresetDialog(std::vector<Preset::Type> types, std::string suffix)
|
||||||
|
: DPIDialog(nullptr, wxID_ANY, _L("Save preset"), wxDefaultPosition, wxSize(45 * wxGetApp().em_unit(), 5 * wxGetApp().em_unit()), wxDEFAULT_DIALOG_STYLE | wxICON_WARNING | wxRESIZE_BORDER)
|
||||||
|
{
|
||||||
|
build(types, suffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
SavePresetDialog::~SavePresetDialog()
|
||||||
|
{
|
||||||
|
for (auto item : m_items) {
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SavePresetDialog::build(std::vector<Preset::Type> types, std::string suffix)
|
||||||
{
|
{
|
||||||
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||||
#if ENABLE_WX_3_1_3_DPI_CHANGED_EVENT
|
#if ENABLE_WX_3_1_3_DPI_CHANGED_EVENT
|
||||||
|
@ -1179,14 +1197,18 @@ SavePresetDialog::SavePresetDialog(Preset::Type type, const std::string& suffix)
|
||||||
// Because of from wxWidgets 3.1.3 auto rescaling is implemented for the Fonts,
|
// Because of from wxWidgets 3.1.3 auto rescaling is implemented for the Fonts,
|
||||||
// From the very beginning set dialog font to the wxSYS_DEFAULT_GUI_FONT
|
// From the very beginning set dialog font to the wxSYS_DEFAULT_GUI_FONT
|
||||||
this->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
|
this->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
|
||||||
#endif // ENABLE_WX_3_1_3_DPI_CHANGED_EVENT
|
#endif // ENABLE_WX_3_1_3_DPI_CHANGED_EVENT
|
||||||
|
|
||||||
|
if (suffix.empty())
|
||||||
|
suffix = _CTX_utf8(L_CONTEXT("Copy", "PresetName"), "PresetName");
|
||||||
|
|
||||||
wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL);
|
wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL);
|
||||||
|
|
||||||
m_presets_sizer = new wxBoxSizer(wxVERTICAL);
|
m_presets_sizer = new wxBoxSizer(wxVERTICAL);
|
||||||
|
|
||||||
// Add first item
|
// Add first item
|
||||||
m_items.emplace_back(type, suffix, m_presets_sizer, this);
|
for (Preset::Type type : types)
|
||||||
|
AddItem(type, suffix);
|
||||||
|
|
||||||
// Add dialog's buttons
|
// Add dialog's buttons
|
||||||
wxStdDialogButtonSizer* btns = this->CreateStdDialogButtonSizer(wxOK | wxCANCEL);
|
wxStdDialogButtonSizer* btns = this->CreateStdDialogButtonSizer(wxOK | wxCANCEL);
|
||||||
|
@ -1203,26 +1225,26 @@ SavePresetDialog::SavePresetDialog(Preset::Type type, const std::string& suffix)
|
||||||
|
|
||||||
void SavePresetDialog::AddItem(Preset::Type type, const std::string& suffix)
|
void SavePresetDialog::AddItem(Preset::Type type, const std::string& suffix)
|
||||||
{
|
{
|
||||||
m_items.emplace_back(type, suffix, m_presets_sizer, this);
|
m_items.emplace_back(new Item{type, suffix, m_presets_sizer, this});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SavePresetDialog::get_name()
|
std::string SavePresetDialog::get_name()
|
||||||
{
|
{
|
||||||
return m_items.front().preset_name();
|
return m_items.front()->preset_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SavePresetDialog::get_name(Preset::Type type)
|
std::string SavePresetDialog::get_name(Preset::Type type)
|
||||||
{
|
{
|
||||||
for (Item& item : m_items)
|
for (const Item* item : m_items)
|
||||||
if (item.type() == type)
|
if (item->type() == type)
|
||||||
return item.preset_name();
|
return item->preset_name();
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SavePresetDialog::enable_ok_btn() const
|
bool SavePresetDialog::enable_ok_btn() const
|
||||||
{
|
{
|
||||||
for (Item item : m_items)
|
for (const Item* item : m_items)
|
||||||
if (!item.is_valid())
|
if (!item->is_valid())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1291,8 +1313,8 @@ void SavePresetDialog::on_dpi_changed(const wxRect& suggested_rect)
|
||||||
|
|
||||||
msw_buttons_rescale(this, em, { wxID_OK, wxID_CANCEL });
|
msw_buttons_rescale(this, em, { wxID_OK, wxID_CANCEL });
|
||||||
|
|
||||||
for (Item& item : m_items)
|
for (Item* item : m_items)
|
||||||
item.update_valid_bmp();
|
item->update_valid_bmp();
|
||||||
|
|
||||||
//const wxSize& size = wxSize(45 * em, 35 * em);
|
//const wxSize& size = wxSize(45 * em, 35 * em);
|
||||||
SetMinSize(/*size*/wxSize(100, 50));
|
SetMinSize(/*size*/wxSize(100, 50));
|
||||||
|
@ -1331,10 +1353,10 @@ void SavePresetDialog::update_physical_printers(const std::string& preset_name)
|
||||||
|
|
||||||
void SavePresetDialog::accept()
|
void SavePresetDialog::accept()
|
||||||
{
|
{
|
||||||
for (Item& item : m_items) {
|
for (Item* item : m_items) {
|
||||||
item.accept();
|
item->accept();
|
||||||
if (item.type() == Preset::TYPE_PRINTER)
|
if (item->type() == Preset::TYPE_PRINTER)
|
||||||
update_physical_printers(item.preset_name());
|
update_physical_printers(item->preset_name());
|
||||||
}
|
}
|
||||||
|
|
||||||
EndModal(wxID_OK);
|
EndModal(wxID_OK);
|
||||||
|
|
|
@ -235,7 +235,7 @@ class SavePresetDialog : public DPIDialog
|
||||||
void update();
|
void update();
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<Item> m_items;
|
std::vector<Item*> m_items;
|
||||||
|
|
||||||
wxBoxSizer* m_presets_sizer {nullptr};
|
wxBoxSizer* m_presets_sizer {nullptr};
|
||||||
wxStaticText* m_label {nullptr};
|
wxStaticText* m_label {nullptr};
|
||||||
|
@ -248,8 +248,9 @@ class SavePresetDialog : public DPIDialog
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SavePresetDialog(Preset::Type type, const std::string& suffix);
|
SavePresetDialog(Preset::Type type, std::string suffix = "");
|
||||||
~SavePresetDialog() {}
|
SavePresetDialog(std::vector<Preset::Type> types, std::string suffix = "");
|
||||||
|
~SavePresetDialog();
|
||||||
|
|
||||||
void AddItem(Preset::Type type, const std::string& suffix);
|
void AddItem(Preset::Type type, const std::string& suffix);
|
||||||
|
|
||||||
|
@ -266,6 +267,7 @@ protected:
|
||||||
void on_sys_color_changed() override {}
|
void on_sys_color_changed() override {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void build(std::vector<Preset::Type> types, std::string suffix = "");
|
||||||
void update_physical_printers(const std::string& preset_name);
|
void update_physical_printers(const std::string& preset_name);
|
||||||
void accept();
|
void accept();
|
||||||
};
|
};
|
||||||
|
|
|
@ -3146,36 +3146,27 @@ bool Tab::may_discard_current_dirty_preset(PresetCollection* presets /*= nullptr
|
||||||
|
|
||||||
if (dlg.save_preset()) // save selected changes
|
if (dlg.save_preset()) // save selected changes
|
||||||
{
|
{
|
||||||
std::vector<std::string> unselected_options = dlg.get_unselected_options();
|
std::vector<std::string> unselected_options = dlg.get_unselected_options(presets->type());
|
||||||
const Preset& preset = presets->get_edited_preset();
|
const Preset& preset = presets->get_edited_preset();
|
||||||
std::string name = preset.name;
|
std::string name = preset.name;
|
||||||
|
|
||||||
// for system/default/external presets we should take an edited name
|
// for system/default/external presets we should take an edited name
|
||||||
if (preset.is_system || preset.is_default || preset.is_external) {
|
if (preset.is_system || preset.is_default || preset.is_external) {
|
||||||
SavePresetDialog save_dlg(preset.type, _CTX_utf8(L_CONTEXT("Copy", "PresetName"), "PresetName"));
|
SavePresetDialog save_dlg(preset.type);
|
||||||
if (save_dlg.ShowModal() != wxID_OK)
|
if (save_dlg.ShowModal() != wxID_OK)
|
||||||
return false;
|
return false;
|
||||||
name = save_dlg.get_name();
|
name = save_dlg.get_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we want to save just some from selected options
|
if (m_type == presets->type()) // save changes for the current preset from this tab
|
||||||
if (!unselected_options.empty())
|
|
||||||
{
|
{
|
||||||
DynamicPrintConfig& old_config = presets->get_selected_preset().config;
|
|
||||||
// revert unselected options to the old values
|
// revert unselected options to the old values
|
||||||
for (const std::string& opt_key : unselected_options)
|
presets->get_edited_preset().config.apply_only(presets->get_selected_preset().config, unselected_options);
|
||||||
presets->get_edited_preset().config.set_key_value(opt_key, old_config.option(opt_key)->clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_type == presets->type()) // save changes for the current preset
|
|
||||||
save_preset(name);
|
save_preset(name);
|
||||||
else // save changes for dependent preset
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// Save the preset into Slic3r::data_dir / presets / section_name / preset_name.ini
|
m_preset_bundle->save_changes_for_preset(name, presets->type(), unselected_options);
|
||||||
presets->save_current_preset(name);
|
|
||||||
// Mark the print & filament enabled if they are compatible with the currently selected preset.
|
|
||||||
// If saving the preset changes compatibility with other presets, keep the now incompatible dependent presets selected, however with a "red flag" icon showing that they are no more compatible.
|
|
||||||
m_preset_bundle->update_compatible(PresetSelectCompatibleType::Never);
|
|
||||||
|
|
||||||
/* If filament preset is saved for multi-material printer preset,
|
/* If filament preset is saved for multi-material printer preset,
|
||||||
* there are cases when filament comboboxs are updated for old (non-modified) colors,
|
* there are cases when filament comboboxs are updated for old (non-modified) colors,
|
||||||
|
@ -3283,10 +3274,8 @@ void Tab::save_preset(std::string name /*= ""*/, bool detach)
|
||||||
// focus currently.is there anything better than this ?
|
// focus currently.is there anything better than this ?
|
||||||
//! m_treectrl->OnSetFocus();
|
//! m_treectrl->OnSetFocus();
|
||||||
|
|
||||||
std::string suffix = detach ? _utf8(L("Detached")) : _CTX_utf8(L_CONTEXT("Copy", "PresetName"), "PresetName");
|
|
||||||
|
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
SavePresetDialog dlg(m_type, suffix);
|
SavePresetDialog dlg(m_type, detach ? _u8L("Detached") : "");
|
||||||
if (dlg.ShowModal() != wxID_OK)
|
if (dlg.ShowModal() != wxID_OK)
|
||||||
return;
|
return;
|
||||||
name = dlg.get_name();
|
name = dlg.get_name();
|
||||||
|
|
|
@ -514,8 +514,19 @@ void UnsavedChangesModel::Rescale()
|
||||||
// UnsavedChangesDialog
|
// UnsavedChangesDialog
|
||||||
//------------------------------------------
|
//------------------------------------------
|
||||||
|
|
||||||
|
UnsavedChangesDialog::UnsavedChangesDialog(const wxString& header)
|
||||||
|
: DPIDialog(nullptr, wxID_ANY, _L("Unsaved Changes"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
||||||
|
{
|
||||||
|
build(Preset::TYPE_INVALID, nullptr, "", header);
|
||||||
|
}
|
||||||
|
|
||||||
UnsavedChangesDialog::UnsavedChangesDialog(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset)
|
UnsavedChangesDialog::UnsavedChangesDialog(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset)
|
||||||
: DPIDialog(nullptr, wxID_ANY, _L("Unsaved Changes"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
: DPIDialog(nullptr, wxID_ANY, _L("Unsaved Changes"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
||||||
|
{
|
||||||
|
build(type, dependent_presets, new_selected_preset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnsavedChangesDialog::build(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset, const wxString& header)
|
||||||
{
|
{
|
||||||
wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
|
wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
|
||||||
SetBackgroundColour(bgr_clr);
|
SetBackgroundColour(bgr_clr);
|
||||||
|
@ -579,7 +590,8 @@ UnsavedChangesDialog::UnsavedChangesDialog(Preset::Type type, PresetCollection*
|
||||||
|
|
||||||
int btn_idx = 0;
|
int btn_idx = 0;
|
||||||
add_btn(&m_save_btn, m_save_btn_id, "save", Action::Save, btn_idx++);
|
add_btn(&m_save_btn, m_save_btn_id, "save", Action::Save, btn_idx++);
|
||||||
if (type == dependent_presets->type())
|
if (type != Preset::TYPE_INVALID && type == dependent_presets->type() &&
|
||||||
|
dependent_presets->get_edited_preset().printer_technology() == dependent_presets->find_preset(new_selected_preset)->printer_technology())
|
||||||
add_btn(&m_move_btn, m_move_btn_id, "paste_menu", Action::Move, btn_idx++);
|
add_btn(&m_move_btn, m_move_btn_id, "paste_menu", Action::Move, btn_idx++);
|
||||||
add_btn(&m_continue_btn, m_continue_btn_id, "cross", Action::Continue, btn_idx, false);
|
add_btn(&m_continue_btn, m_continue_btn_id, "cross", Action::Continue, btn_idx, false);
|
||||||
|
|
||||||
|
@ -594,7 +606,7 @@ UnsavedChangesDialog::UnsavedChangesDialog(Preset::Type type, PresetCollection*
|
||||||
topSizer->Add(m_info_line, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, 2*border);
|
topSizer->Add(m_info_line, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, 2*border);
|
||||||
topSizer->Add(buttons, 0, wxEXPAND | wxALL, border);
|
topSizer->Add(buttons, 0, wxEXPAND | wxALL, border);
|
||||||
|
|
||||||
update(type, dependent_presets, new_selected_preset);
|
update(type, dependent_presets, new_selected_preset, header);
|
||||||
|
|
||||||
SetSizer(topSizer);
|
SetSizer(topSizer);
|
||||||
topSizer->SetSizeHints(this);
|
topSizer->SetSizeHints(this);
|
||||||
|
@ -654,8 +666,12 @@ void UnsavedChangesDialog::show_info_line(Action action, std::string preset_name
|
||||||
else if (action == Action::Continue)
|
else if (action == Action::Continue)
|
||||||
text = _L("All changed options will be reverted.");
|
text = _L("All changed options will be reverted.");
|
||||||
else {
|
else {
|
||||||
std::string act_string = action == Action::Save ? _u8L("saved") : _u8L("moved");
|
if (action == Action::Save && preset_name.empty())
|
||||||
text = from_u8((boost::format("After press this button selected options will be %1% to the preset \"%2%\".") % act_string % preset_name).str());
|
text = _L("After press this button selected options will be saved");
|
||||||
|
else {
|
||||||
|
std::string act_string = action == Action::Save ? _u8L("saved") : _u8L("moved");
|
||||||
|
text = from_u8((boost::format("After press this button selected options will be %1% to the preset \"%2%\".") % act_string % preset_name).str());
|
||||||
|
}
|
||||||
text += "\n" + _L("Unselected options will be reverted.");
|
text += "\n" + _L("Unselected options will be reverted.");
|
||||||
}
|
}
|
||||||
m_info_line->SetLabel(text);
|
m_info_line->SetLabel(text);
|
||||||
|
@ -815,64 +831,92 @@ wxString UnsavedChangesDialog::get_short_string(wxString full_string)
|
||||||
return full_string + dots;
|
return full_string + dots;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnsavedChangesDialog::update(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset)
|
void UnsavedChangesDialog::update(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset, const wxString& header)
|
||||||
{
|
{
|
||||||
PresetCollection* presets = dependent_presets;
|
PresetCollection* presets = dependent_presets;
|
||||||
|
|
||||||
// activate buttons and labels
|
// activate buttons and labels
|
||||||
m_save_btn ->Bind(wxEVT_ENTER_WINDOW, [this, presets] (wxMouseEvent& e) { show_info_line(Action::Save, presets->get_selected_preset().name); e.Skip(); });
|
m_save_btn ->Bind(wxEVT_ENTER_WINDOW, [this, presets] (wxMouseEvent& e) { show_info_line(Action::Save, presets ? presets->get_selected_preset().name : ""); e.Skip(); });
|
||||||
if (m_move_btn)
|
if (m_move_btn)
|
||||||
m_move_btn ->Bind(wxEVT_ENTER_WINDOW, [this, new_selected_preset] (wxMouseEvent& e) { show_info_line(Action::Move, new_selected_preset); e.Skip(); });
|
m_move_btn ->Bind(wxEVT_ENTER_WINDOW, [this, new_selected_preset] (wxMouseEvent& e) { show_info_line(Action::Move, new_selected_preset); e.Skip(); });
|
||||||
m_continue_btn ->Bind(wxEVT_ENTER_WINDOW, [this] (wxMouseEvent& e) { show_info_line(Action::Continue); e.Skip(); });
|
m_continue_btn ->Bind(wxEVT_ENTER_WINDOW, [this] (wxMouseEvent& e) { show_info_line(Action::Continue); e.Skip(); });
|
||||||
|
|
||||||
m_save_btn->SetLabel(from_u8((boost::format(_u8L("Save selected to preset: %1%")) % ("\"" + presets->get_selected_preset().name + "\"")).str()));
|
|
||||||
m_continue_btn->SetLabel(_L("Continue without changes"));
|
m_continue_btn->SetLabel(_L("Continue without changes"));
|
||||||
|
|
||||||
wxString action_msg;
|
if (type == Preset::TYPE_INVALID) {
|
||||||
if (type == dependent_presets->type()) {
|
m_action_line ->SetLabel(header + "\n" + _L("Next presets have the following unsaved changes:"));
|
||||||
action_msg = _L("has the following unsaved changes:");
|
m_save_btn ->SetLabel(_L("Save selected"));
|
||||||
|
|
||||||
m_move_btn->SetLabel(from_u8((boost::format(_u8L("Move selected to preset: %1%")) % ("\"" + new_selected_preset + "\"")).str()));
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
action_msg = type == Preset::TYPE_PRINTER ?
|
wxString action_msg;
|
||||||
_L("is not compatible with printer") :
|
if (type == dependent_presets->type()) {
|
||||||
_L("is not compatible with print profile");
|
action_msg = _L("has the following unsaved changes:");
|
||||||
action_msg += " \"" + from_u8(new_selected_preset) + "\" ";
|
if (m_move_btn)
|
||||||
action_msg += _L("and it has the following unsaved changes:");
|
m_move_btn->SetLabel(from_u8((boost::format(_u8L("Move selected to preset: %1%")) % ("\"" + new_selected_preset + "\"")).str()));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
action_msg = type == Preset::TYPE_PRINTER ?
|
||||||
|
_L("is not compatible with printer") :
|
||||||
|
_L("is not compatible with print profile");
|
||||||
|
action_msg += " \"" + from_u8(new_selected_preset) + "\"\n";
|
||||||
|
action_msg += _L("and it has the following unsaved changes:");
|
||||||
|
}
|
||||||
|
m_action_line->SetLabel(from_u8((boost::format(_utf8(L("Preset \"%1%\" %2%"))) % _utf8(presets->get_edited_preset().name) % action_msg).str()));
|
||||||
|
m_save_btn->SetLabel(from_u8((boost::format(_u8L("Save selected to preset: %1%")) % ("\"" + presets->get_selected_preset().name + "\"")).str()));
|
||||||
}
|
}
|
||||||
m_action_line->SetLabel(from_u8((boost::format(_utf8(L("Preset \"%1%\" %2%"))) % _utf8(presets->get_edited_preset().name) % action_msg).str()));
|
|
||||||
|
|
||||||
// Display a dialog showing the dirty options in a human readable form.
|
update_tree(type, presets);
|
||||||
const DynamicPrintConfig& old_config = presets->get_selected_preset().config;
|
}
|
||||||
const DynamicPrintConfig& new_config = presets->get_edited_preset().config;
|
|
||||||
|
|
||||||
m_tree_model->AddPreset(type, from_u8(presets->get_edited_preset().name));
|
|
||||||
|
|
||||||
|
void UnsavedChangesDialog::update_tree(Preset::Type type, PresetCollection* presets_)
|
||||||
|
{
|
||||||
Search::OptionsSearcher& searcher = wxGetApp().sidebar().get_searcher();
|
Search::OptionsSearcher& searcher = wxGetApp().sidebar().get_searcher();
|
||||||
searcher.sort_options_by_opt_key();
|
searcher.sort_options_by_opt_key();
|
||||||
|
|
||||||
// Collect dirty options.
|
// list of the presets with unsaved changes
|
||||||
for (const std::string& opt_key : presets->current_dirty_options()) {
|
std::vector<PresetCollection*> presets_list;
|
||||||
const Search::Option& option = searcher.get_option(opt_key);
|
if (type == Preset::TYPE_INVALID)
|
||||||
|
{
|
||||||
|
PrinterTechnology printer_technology = wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology();
|
||||||
|
|
||||||
ItemData item_data = { opt_key, option.label_local, get_string_value(opt_key, old_config), get_string_value(opt_key, new_config) };
|
for (Tab* tab : wxGetApp().tabs_list)
|
||||||
|
if (tab->supports_printer_technology(printer_technology) && tab->current_preset_is_dirty())
|
||||||
|
presets_list.emplace_back(tab->get_presets());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
presets_list.emplace_back(presets_);
|
||||||
|
|
||||||
wxString old_val = get_short_string(item_data.old_val);
|
// Display a dialog showing the dirty options in a human readable form.
|
||||||
wxString new_val = get_short_string(item_data.new_val);
|
for (PresetCollection* presets : presets_list)
|
||||||
if (old_val != item_data.old_val || new_val != item_data.new_val)
|
{
|
||||||
item_data.is_long = true;
|
const DynamicPrintConfig& old_config = presets->get_selected_preset().config;
|
||||||
|
const DynamicPrintConfig& new_config = presets->get_edited_preset().config;
|
||||||
|
type = presets->type();
|
||||||
|
|
||||||
m_items_map.emplace(m_tree_model->AddOption(type, option.category_local, option.group_local, option.label_local, old_val, new_val), item_data);
|
m_tree_model->AddPreset(type, from_u8(presets->get_edited_preset().name));
|
||||||
|
|
||||||
|
// Collect dirty options.
|
||||||
|
for (const std::string& opt_key : presets->current_dirty_options()) {
|
||||||
|
const Search::Option& option = searcher.get_option(opt_key);
|
||||||
|
|
||||||
|
ItemData item_data = { opt_key, option.label_local, get_string_value(opt_key, old_config), get_string_value(opt_key, new_config), type };
|
||||||
|
|
||||||
|
wxString old_val = get_short_string(item_data.old_val);
|
||||||
|
wxString new_val = get_short_string(item_data.new_val);
|
||||||
|
if (old_val != item_data.old_val || new_val != item_data.new_val)
|
||||||
|
item_data.is_long = true;
|
||||||
|
|
||||||
|
m_items_map.emplace(m_tree_model->AddOption(type, option.category_local, option.group_local, option.label_local, old_val, new_val), item_data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> UnsavedChangesDialog::get_unselected_options()
|
std::vector<std::string> UnsavedChangesDialog::get_unselected_options(Preset::Type type)
|
||||||
{
|
{
|
||||||
std::vector<std::string> ret;
|
std::vector<std::string> ret;
|
||||||
|
|
||||||
for (auto item : m_items_map)
|
for (auto item : m_items_map)
|
||||||
if (!m_tree_model->IsEnabledItem(item.first))
|
if (item.second.type == type && !m_tree_model->IsEnabledItem(item.first))
|
||||||
ret.emplace_back(item.second.opt_key);
|
ret.emplace_back(item.second.opt_key);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -217,22 +217,26 @@ class UnsavedChangesDialog : public DPIDialog
|
||||||
|
|
||||||
struct ItemData
|
struct ItemData
|
||||||
{
|
{
|
||||||
std::string opt_key;
|
std::string opt_key;
|
||||||
wxString opt_name;
|
wxString opt_name;
|
||||||
wxString old_val;
|
wxString old_val;
|
||||||
wxString new_val;
|
wxString new_val;
|
||||||
bool is_long {false};
|
Preset::Type type;
|
||||||
|
bool is_long {false};
|
||||||
};
|
};
|
||||||
// tree items related to the options
|
// tree items related to the options
|
||||||
std::map<wxDataViewItem, ItemData> m_items_map;
|
std::map<wxDataViewItem, ItemData> m_items_map;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
UnsavedChangesDialog(const wxString& header);
|
||||||
UnsavedChangesDialog(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset);
|
UnsavedChangesDialog(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset);
|
||||||
~UnsavedChangesDialog() {}
|
~UnsavedChangesDialog() {}
|
||||||
|
|
||||||
wxString get_short_string(wxString full_string);
|
wxString get_short_string(wxString full_string);
|
||||||
|
|
||||||
void update(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset);
|
void build(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset, const wxString& header = "");
|
||||||
|
void update(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset, const wxString& header);
|
||||||
|
void update_tree(Preset::Type type, PresetCollection *presets);
|
||||||
void item_value_changed(wxDataViewEvent &event);
|
void item_value_changed(wxDataViewEvent &event);
|
||||||
void context_menu(wxDataViewEvent &event);
|
void context_menu(wxDataViewEvent &event);
|
||||||
void show_info_line(Action action, std::string preset_name = "");
|
void show_info_line(Action action, std::string preset_name = "");
|
||||||
|
@ -242,7 +246,7 @@ public:
|
||||||
bool move_preset() const { return m_exit_action == Action::Move; }
|
bool move_preset() const { return m_exit_action == Action::Move; }
|
||||||
bool just_continue() const { return m_exit_action == Action::Continue; }
|
bool just_continue() const { return m_exit_action == Action::Continue; }
|
||||||
|
|
||||||
std::vector<std::string> get_unselected_options();
|
std::vector<std::string> get_unselected_options(Preset::Type type);
|
||||||
std::vector<std::string> get_selected_options();
|
std::vector<std::string> get_selected_options();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
Loading…
Reference in a new issue