UnsavedChangesDialog : improvements

* Added "Remember my choice" checkbox
* Center on the screen and set position in respect to the position of mainframe or settings dialog

Preferences : Added checkboxes for enable/suppress showing of the UnsavedChangeDialog

SearchImGui : close after parameter selection_is_changed_according_to_physical_printers

PhysicalPrinterDialog, SavePresetDialog : Center on the screen
This commit is contained in:
YuSanka 2020-10-15 16:48:48 +02:00 committed by Oleksandra Yushchenko
parent 650bbb3484
commit 00a7799341
12 changed files with 171 additions and 58 deletions

View File

@ -122,6 +122,12 @@ void AppConfig::set_defaults()
if (get("show_splash_screen").empty()) if (get("show_splash_screen").empty())
set("show_splash_screen", "1"); set("show_splash_screen", "1");
if (get("default_action_on_close_application").empty())
set("default_action_on_close_application", "none"); // , "discard" or "save"
if (get("default_action_on_select_preset").empty())
set("default_action_on_select_preset", "none"); // , "transfer", "discard" or "save"
// Remove legacy window positions/sizes // Remove legacy window positions/sizes
erase("", "main_frame_maximized"); erase("", "main_frame_maximized");
erase("", "main_frame_pos"); erase("", "main_frame_pos");

View File

@ -4429,10 +4429,14 @@ bool GLCanvas3D::_render_search_list(float pos_x) const
if (selected >= 0) { if (selected >= 0) {
// selected == 9999 means that Esc kye was pressed // selected == 9999 means that Esc kye was pressed
/*// revert commit https://github.com/prusa3d/PrusaSlicer/commit/91897589928789b261ca0dc735ffd46f2b0b99f2
if (selected == 9999) if (selected == 9999)
action_taken = true; action_taken = true;
else else
sidebar.jump_to_option(selected);*/
if (selected != 9999)
sidebar.jump_to_option(selected); sidebar.jump_to_option(selected);
action_taken = true;
} }
imgui->end(); imgui->end();

View File

@ -1654,7 +1654,7 @@ bool GUI_App::check_unsaved_changes(const wxString &header)
if (has_unsaved_changes) if (has_unsaved_changes)
{ {
UnsavedChangesDialog dlg(header); UnsavedChangesDialog dlg(header);
if (dlg.ShowModal() == wxID_CANCEL) if (wxGetApp().app_config->get("default_action_on_close_application") == "none" && dlg.ShowModal() == wxID_CANCEL)
return false; return false;
if (dlg.save_preset()) // save selected changes if (dlg.save_preset()) // save selected changes

View File

@ -170,6 +170,7 @@ public:
void update_ui_from_settings(); void update_ui_from_settings();
bool is_loaded() const { return m_loaded; } bool is_loaded() const { return m_loaded; }
bool is_last_input_file() const { return !m_qs_last_input_file.IsEmpty(); } bool is_last_input_file() const { return !m_qs_last_input_file.IsEmpty(); }
bool is_dlg_layout() const { return m_layout == ESettingsLayout::Dlg; }
void quick_slice(const int qs = qsUndef); void quick_slice(const int qs = qsUndef);
void reslice_now(); void reslice_now();

View File

@ -236,6 +236,8 @@ PhysicalPrinterDialog::PhysicalPrinterDialog(wxString printer_name) :
m_printer_name->SetFocus(); m_printer_name->SetFocus();
m_printer_name->SelectAll(); m_printer_name->SelectAll();
} }
this->CenterOnScreen();
} }
PhysicalPrinterDialog::~PhysicalPrinterDialog() PhysicalPrinterDialog::~PhysicalPrinterDialog()

View File

@ -24,7 +24,10 @@ void PreferencesDialog::build()
m_optgroup_general = std::make_shared<ConfigOptionsGroup>(this, _L("General")); m_optgroup_general = std::make_shared<ConfigOptionsGroup>(this, _L("General"));
m_optgroup_general->label_width = 40; m_optgroup_general->label_width = 40;
m_optgroup_general->m_on_change = [this](t_config_option_key opt_key, boost::any value) { m_optgroup_general->m_on_change = [this](t_config_option_key opt_key, boost::any value) {
m_values[opt_key] = boost::any_cast<bool>(value) ? "1" : "0"; if (opt_key == "default_action_on_close_application" || opt_key == "default_action_on_select_preset")
m_values[opt_key] = boost::any_cast<bool>(value) ? "none" : "discard";
else
m_values[opt_key] = boost::any_cast<bool>(value) ? "1" : "0";
}; };
// TODO // TODO
@ -148,6 +151,20 @@ void PreferencesDialog::build()
m_optgroup_general->append_single_option_line(option); m_optgroup_general->append_single_option_line(option);
*/ */
def.label = L("Ask for unsaved changes when closing application");
def.type = coBool;
def.tooltip = L("Always ask for unsaved changes when closing application");
def.set_default_value(new ConfigOptionBool{ app_config->get("default_action_on_close_application") == "none" });
option = Option(def, "default_action_on_close_application");
m_optgroup_general->append_single_option_line(option);
def.label = L("Ask for unsaved changes when selecting new preset");
def.type = coBool;
def.tooltip = L("Always ask for unsaved changes when selecting new preset");
def.set_default_value(new ConfigOptionBool{ app_config->get("default_action_on_select_preset") == "none" });
option = Option(def, "default_action_on_select_preset");
m_optgroup_general->append_single_option_line(option);
// Show/Hide splash screen // Show/Hide splash screen
def.label = L("Show splash screen"); def.label = L("Show splash screen");
def.type = coBool; def.type = coBool;
@ -300,6 +317,13 @@ void PreferencesDialog::accept()
} }
} }
for (const std::string& key : {"default_action_on_close_application", "default_action_on_select_preset"})
{
auto it = m_values.find(key);
if (it != m_values.end() && it->second != "none" && app_config->get(key) != "none")
m_values.erase(it); // we shouldn't change value, if some of those parameters was selected, and then deselected
}
for (std::map<std::string, std::string>::iterator it = m_values.begin(); it != m_values.end(); ++it) for (std::map<std::string, std::string>::iterator it = m_values.begin(); it != m_values.end(); ++it)
app_config->set(it->first, it->second); app_config->set(it->first, it->second);

View File

@ -1221,6 +1221,8 @@ void SavePresetDialog::build(std::vector<Preset::Type> types, std::string suffix
SetSizer(topSizer); SetSizer(topSizer);
topSizer->SetSizeHints(this); topSizer->SetSizeHints(this);
this->CenterOnScreen();
} }
void SavePresetDialog::AddItem(Preset::Type type, const std::string& suffix) void SavePresetDialog::AddItem(Preset::Type type, const std::string& suffix)

View File

@ -3099,7 +3099,7 @@ bool Tab::may_discard_current_dirty_preset(PresetCollection* presets /*= nullptr
if (presets == nullptr) presets = m_presets; if (presets == nullptr) presets = m_presets;
UnsavedChangesDialog dlg(m_type, presets, new_printer_name); UnsavedChangesDialog dlg(m_type, presets, new_printer_name);
if (dlg.ShowModal() == wxID_CANCEL) if (wxGetApp().app_config->get("default_action_on_select_preset") == "none" && dlg.ShowModal() == wxID_CANCEL)
return false; return false;
if (dlg.save_preset()) // save selected changes if (dlg.save_preset()) // save selected changes
@ -3124,7 +3124,7 @@ bool Tab::may_discard_current_dirty_preset(PresetCollection* presets /*= nullptr
wxGetApp().plater()->force_filament_colors_update(); wxGetApp().plater()->force_filament_colors_update();
} }
} }
else if (dlg.move_preset()) // move selected changes else if (dlg.transfer_changes()) // move selected changes
{ {
std::vector<std::string> selected_options = dlg.get_selected_options(); std::vector<std::string> selected_options = dlg.get_selected_options();
if (m_type == presets->type()) // move changes for the current preset from this tab if (m_type == presets->type()) // move changes for the current preset from this tab

View File

@ -14,6 +14,7 @@
#include "ExtraRenderers.hpp" #include "ExtraRenderers.hpp"
#include "wxExtensions.hpp" #include "wxExtensions.hpp"
#include "PresetComboBoxes.hpp" #include "PresetComboBoxes.hpp"
#include "MainFrame.hpp"
//#define FTS_FUZZY_MATCH_IMPLEMENTATION //#define FTS_FUZZY_MATCH_IMPLEMENTATION
//#include "fts_fuzzy_match.h" //#include "fts_fuzzy_match.h"
@ -526,15 +527,45 @@ void UnsavedChangesModel::Rescale()
//------------------------------------------ //------------------------------------------
UnsavedChangesDialog::UnsavedChangesDialog(const wxString& header) UnsavedChangesDialog::UnsavedChangesDialog(const wxString& header)
: DPIDialog(nullptr, wxID_ANY, _L("Close Aplication: Unsaved Changes"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) : DPIDialog(nullptr, wxID_ANY, _L("Close Application: Unsaved Changes"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{ {
m_app_config_key = "default_action_on_close_application";
build(Preset::TYPE_INVALID, nullptr, "", header); build(Preset::TYPE_INVALID, nullptr, "", header);
const std::string& def_action = wxGetApp().app_config->get(m_app_config_key);
if (def_action == "none")
this->CenterOnScreen();
else {
m_exit_action = def_action == ActSave ? Action::Save : Action::Discard;
if (m_exit_action == Action::Save)
save(nullptr);
}
} }
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("Select New Preset: Unsaved Changes"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) : DPIDialog(nullptr, wxID_ANY, _L("Select New Preset: Unsaved Changes"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{ {
m_app_config_key = "default_action_on_select_preset";
build(type, dependent_presets, new_selected_preset); build(type, dependent_presets, new_selected_preset);
const std::string& def_action = wxGetApp().app_config->get(m_app_config_key);
if (def_action == "none") {
if (wxGetApp().mainframe->is_dlg_layout())
this->SetPosition(wxGetApp().mainframe->m_settings_dialog.GetPosition());
this->CenterOnScreen();
}
else {
m_exit_action = def_action == ActTransfer ? Action::Transfer :
def_action == ActSave ? Action::Save : Action::Discard;
const PresetCollection& printers = wxGetApp().preset_bundle->printers;
if (m_exit_action == Action::Save ||
(m_exit_action == Action::Transfer && dependent_presets && (type == dependent_presets->type() ?
dependent_presets->get_edited_preset().printer_technology() != dependent_presets->find_preset(new_selected_preset)->printer_technology() :
printers.get_edited_preset().printer_technology() != printers.find_preset(new_selected_preset)->printer_technology())) )
save(dependent_presets);
}
} }
void UnsavedChangesDialog::build(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset, const wxString& header) void UnsavedChangesDialog::build(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset, const wxString& header)
@ -555,7 +586,7 @@ void UnsavedChangesDialog::build(Preset::Type type, PresetCollection* dependent_
m_action_line = new wxStaticText(this, wxID_ANY, ""); m_action_line = new wxStaticText(this, wxID_ANY, "");
m_action_line->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold()); m_action_line->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold());
m_tree = new wxDataViewCtrl(this, wxID_ANY, wxDefaultPosition, wxSize(em * 80, em * 30), wxBORDER_SIMPLE | wxDV_VARIABLE_LINE_HEIGHT | wxDV_ROW_LINES); m_tree = new wxDataViewCtrl(this, wxID_ANY, wxDefaultPosition, wxSize(em * 60, em * 30), wxBORDER_SIMPLE | wxDV_VARIABLE_LINE_HEIGHT | wxDV_ROW_LINES);
m_tree_model = new UnsavedChangesModel(this); m_tree_model = new UnsavedChangesModel(this);
m_tree->AssociateModel(m_tree_model); m_tree->AssociateModel(m_tree_model);
m_tree_model->SetAssociatedControl(m_tree); m_tree_model->SetAssociatedControl(m_tree);
@ -578,47 +609,76 @@ void UnsavedChangesDialog::build(Preset::Type type, PresetCollection* dependent_
m_tree->SetExpanderColumn(column); m_tree->SetExpanderColumn(column);
}; };
append_bmp_text_column("", UnsavedChangesModel::colIconText, 30 * em); append_bmp_text_column("" , UnsavedChangesModel::colIconText, 28 * em);
append_bmp_text_column(_L("Old Value"), UnsavedChangesModel::colOldValue, 20 * em); append_bmp_text_column(_L("Old Value"), UnsavedChangesModel::colOldValue, 12 * em);
append_bmp_text_column(_L("New Value"), UnsavedChangesModel::colNewValue, 20 * em); append_bmp_text_column(_L("New Value"), UnsavedChangesModel::colNewValue, 12 * em);
m_tree->Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, &UnsavedChangesDialog::item_value_changed, this); m_tree->Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, &UnsavedChangesDialog::item_value_changed, this);
m_tree->Bind(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, &UnsavedChangesDialog::context_menu, this); m_tree->Bind(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, &UnsavedChangesDialog::context_menu, this);
// Add Buttons // Add Buttons
wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxCANCEL); wxFont btn_font = this->GetFont().Scaled(1.4f);
wxBoxSizer* buttons = new wxBoxSizer(wxHORIZONTAL);
auto add_btn = [this, buttons, dependent_presets](ScalableButton** btn, int& btn_id, const std::string& icon_name, Action close_act, int idx, bool process_enable = true) auto add_btn = [this, buttons, btn_font, dependent_presets](ScalableButton** btn, int& btn_id, const std::string& icon_name, Action close_act, const wxString& label, bool process_enable = true)
{ {
*btn = new ScalableButton(this, btn_id = NewControlId(), icon_name, "", wxDefaultSize, wxDefaultPosition, wxBORDER_DEFAULT, true); *btn = new ScalableButton(this, btn_id = NewControlId(), icon_name, label, wxDefaultSize, wxDefaultPosition, wxBORDER_DEFAULT, true, 24);
buttons->Insert(idx, *btn, 0, wxLEFT, 5);
(*btn)->Bind(wxEVT_BUTTON, [this, close_act, dependent_presets](wxEvent&) { close_act == Action::Save ? save_and_close(dependent_presets) : close(close_act); }); buttons->Add(*btn, 1, wxLEFT, 5);
(*btn)->SetFont(btn_font);
(*btn)->Bind(wxEVT_BUTTON, [this, close_act, dependent_presets](wxEvent&) {
update_config(close_act);
if (close_act == Action::Save)
save(dependent_presets);
close(close_act);
});
if (process_enable) if (process_enable)
(*btn)->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(!m_empty_selection); }); (*btn)->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(!m_empty_selection); });
(*btn)->Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent& e) { show_info_line(Action::Undef); e.Skip(); }); (*btn)->Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent& e) { show_info_line(Action::Undef); e.Skip(); });
}; };
int btn_idx = 0;
add_btn(&m_save_btn, m_save_btn_id, "save", Action::Save, btn_idx++);
const PresetCollection& printers = wxGetApp().preset_bundle->printers; const PresetCollection& printers = wxGetApp().preset_bundle->printers;
if (dependent_presets && (type == dependent_presets->type() ? if (dependent_presets && (type == dependent_presets->type() ?
dependent_presets->get_edited_preset().printer_technology() == dependent_presets->find_preset(new_selected_preset)->printer_technology() : dependent_presets->get_edited_preset().printer_technology() == dependent_presets->find_preset(new_selected_preset)->printer_technology() :
printers.get_edited_preset().printer_technology() == printers.find_preset(new_selected_preset)->printer_technology() ) ) printers.get_edited_preset().printer_technology() == printers.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_transfer_btn, m_move_btn_id, "paste_menu", Action::Transfer, _L("Transfer"));
add_btn(&m_continue_btn, m_continue_btn_id, dependent_presets ? "cross" : "exit", Action::Continue, btn_idx, false); add_btn(&m_discard_btn, m_continue_btn_id, dependent_presets ? "cross" : "exit", Action::Discard, _L("Discard"), false);
add_btn(&m_save_btn, m_save_btn_id, "save", Action::Save, _L("Save"));
ScalableButton* cancel_btn = new ScalableButton(this, wxID_CANCEL, "cross", _L("Cancel"), wxDefaultSize, wxDefaultPosition, wxBORDER_DEFAULT, true, 24);
buttons->Add(cancel_btn, 1, wxLEFT|wxRIGHT, 5);
cancel_btn->SetFont(btn_font);
cancel_btn->Bind(wxEVT_BUTTON, [this](wxEvent&) { this->EndModal(wxID_CANCEL); });
m_info_line = new wxStaticText(this, wxID_ANY, ""); m_info_line = new wxStaticText(this, wxID_ANY, "");
m_info_line->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold()); m_info_line->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold());
m_info_line->Hide(); m_info_line->Hide();
m_remember_choice = new wxCheckBox(this, wxID_ANY, _L("Remember my choice"));
m_remember_choice->SetValue(wxGetApp().app_config->get(m_app_config_key) != "none");
m_remember_choice->Bind(wxEVT_CHECKBOX, [type](wxCommandEvent& evt)
{
if (!evt.IsChecked())
return;
std::string act = type == Preset::TYPE_INVALID ? _u8L("close the application") : _u8L("select new preset");
std::string preferences_item = type == Preset::TYPE_INVALID ? _u8L("Ask for unsaved changes when closing application") :
_u8L("Ask for unsaved changes when selecting new preset");
std::string msg = (boost::format(_u8L("%1% will remember your action choice.\n"
"You will not be asked about unsaved changes the next time you %2%.\n"
"Visit \"Preferences\" and check \"%3%\"\n"
"to be asked about unsaved changes again.")) % SLIC3R_APP_NAME % act % preferences_item).str();
wxMessageBox(from_u8(msg), _L("Note"),wxOK | wxICON_INFORMATION);
});
wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL);
topSizer->Add(m_action_line,0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, border); topSizer->Add(m_action_line,0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, border);
topSizer->Add(m_tree, 1, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, border); topSizer->Add(m_tree, 1, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, border);
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 | wxLEFT | wxTOP | wxRIGHT, border);
topSizer->Add(m_remember_choice, 0, wxEXPAND | wxALL, border);
update(type, dependent_presets, new_selected_preset, header); update(type, dependent_presets, new_selected_preset, header);
@ -677,10 +737,10 @@ void UnsavedChangesDialog::show_info_line(Action action, std::string preset_name
wxString text; wxString text;
if (action == Action::Undef) if (action == Action::Undef)
text = _L("Some fields are too long to fit. Right click on it to show full text."); text = _L("Some fields are too long to fit. Right click on it to show full text.");
else if (action == Action::Continue) else if (action == Action::Discard)
text = _L("All modified options will be reverted."); text = _L("All modified options will be reverted.");
else { else {
std::string act_string = action == Action::Save ? _u8L("save") : _u8L("move"); std::string act_string = action == Action::Save ? _u8L("save") : _u8L("transfer");
if (preset_name.empty()) if (preset_name.empty())
text = from_u8((boost::format("Press to %1% selected options.") % act_string).str()); text = from_u8((boost::format("Press to %1% selected options.") % act_string).str());
else else
@ -697,13 +757,23 @@ void UnsavedChangesDialog::show_info_line(Action action, std::string preset_name
Refresh(); Refresh();
} }
void UnsavedChangesDialog::update_config(Action action)
{
if (!m_remember_choice->GetValue())
return;
std::string act = action == Action::Transfer ? ActTransfer :
action == Action::Discard ? ActDiscard : ActSave;
wxGetApp().app_config->set(m_app_config_key, act);
}
void UnsavedChangesDialog::close(Action action) void UnsavedChangesDialog::close(Action action)
{ {
m_exit_action = action; m_exit_action = action;
this->EndModal(wxID_CLOSE); this->EndModal(wxID_CLOSE);
} }
void UnsavedChangesDialog::save_and_close(PresetCollection* dependent_presets) void UnsavedChangesDialog::save(PresetCollection* dependent_presets)
{ {
names_and_types.clear(); names_and_types.clear();
@ -715,8 +785,10 @@ void UnsavedChangesDialog::save_and_close(PresetCollection* dependent_presets)
// 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); SavePresetDialog save_dlg(preset.type);
if (save_dlg.ShowModal() != wxID_OK) if (save_dlg.ShowModal() != wxID_OK) {
m_exit_action = Action::Discard;
return; return;
}
name = save_dlg.get_name(); name = save_dlg.get_name();
} }
@ -741,8 +813,10 @@ void UnsavedChangesDialog::save_and_close(PresetCollection* dependent_presets)
if (!types_for_save.empty()) { if (!types_for_save.empty()) {
SavePresetDialog save_dlg(types_for_save); SavePresetDialog save_dlg(types_for_save);
if (save_dlg.ShowModal() != wxID_OK) if (save_dlg.ShowModal() != wxID_OK) {
m_exit_action = Action::Discard;
return; return;
}
for (std::pair<std::string, Preset::Type>& nt : names_and_types) { for (std::pair<std::string, Preset::Type>& nt : names_and_types) {
const std::string& name = save_dlg.get_name(nt.second); const std::string& name = save_dlg.get_name(nt.second);
@ -751,8 +825,6 @@ void UnsavedChangesDialog::save_and_close(PresetCollection* dependent_presets)
} }
} }
} }
close(Action::Save);
} }
template<class T> template<class T>
@ -923,24 +995,20 @@ void UnsavedChangesDialog::update(Preset::Type type, PresetCollection* dependent
// 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 ? 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_transfer_btn) {
bool is_empty_name = type != dependent_presets->type(); bool is_empty_name = type != dependent_presets->type();
m_move_btn ->Bind(wxEVT_ENTER_WINDOW, [this, new_selected_preset, is_empty_name] (wxMouseEvent& e) { show_info_line(Action::Move, is_empty_name ? "" : new_selected_preset); e.Skip(); }); m_transfer_btn ->Bind(wxEVT_ENTER_WINDOW, [this, new_selected_preset, is_empty_name] (wxMouseEvent& e) { show_info_line(Action::Transfer, is_empty_name ? "" : new_selected_preset); e.Skip(); });
} }
m_continue_btn ->Bind(wxEVT_ENTER_WINDOW, [this] (wxMouseEvent& e) { show_info_line(Action::Continue); e.Skip(); }); m_discard_btn ->Bind(wxEVT_ENTER_WINDOW, [this] (wxMouseEvent& e) { show_info_line(Action::Discard); e.Skip(); });
if (type == Preset::TYPE_INVALID) { if (type == Preset::TYPE_INVALID) {
m_action_line ->SetLabel(header + "\n" + _L("Next presets have the following unsaved changes:")); m_action_line ->SetLabel(header + "\n" + _L("Next presets have the following unsaved changes:"));
m_save_btn ->SetLabel(_L("Save selected"));
m_continue_btn ->SetLabel(_L("Close aplication without changes"));
} }
else { else {
wxString action_msg; wxString action_msg;
if (type == dependent_presets->type()) { if (type == dependent_presets->type()) {
action_msg = _L("has the following unsaved changes:"); action_msg = _L("has the following unsaved changes:");
if (m_move_btn)
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 ? action_msg = type == Preset::TYPE_PRINTER ?
@ -948,13 +1016,8 @@ void UnsavedChangesDialog::update(Preset::Type type, PresetCollection* dependent
_L("is not compatible with print profile"); _L("is not compatible with print profile");
action_msg += " \"" + from_u8(new_selected_preset) + "\"\n"; action_msg += " \"" + from_u8(new_selected_preset) + "\"\n";
action_msg += _L("and it has the following unsaved changes:"); action_msg += _L("and it has the following unsaved changes:");
if (m_move_btn)
m_move_btn->SetLabel(_L("Move selected to the first compatible preset"));
} }
m_action_line->SetLabel(from_u8((boost::format(_utf8(L("Preset \"%1%\" %2%"))) % _utf8(presets->get_edited_preset().name) % action_msg).str())); 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_continue_btn->SetLabel(_L("Select new preset without changes"));
} }
update_tree(type, presets); update_tree(type, presets);
@ -1052,8 +1115,8 @@ void UnsavedChangesDialog::on_dpi_changed(const wxRect& suggested_rect)
int em = em_unit(); int em = em_unit();
msw_buttons_rescale(this, em, { wxID_CANCEL, m_save_btn_id, m_move_btn_id, m_continue_btn_id }); msw_buttons_rescale(this, em, { wxID_CANCEL, m_save_btn_id, m_move_btn_id, m_continue_btn_id });
for (auto btn : { m_save_btn, m_move_btn, m_continue_btn } ) for (auto btn : { m_save_btn, m_transfer_btn, m_discard_btn } )
btn->msw_rescale(); if (btn) btn->msw_rescale();
const wxSize& size = wxSize(80 * em, 30 * em); const wxSize& size = wxSize(80 * em, 30 * em);
SetMinSize(size); SetMinSize(size);
@ -1072,7 +1135,7 @@ void UnsavedChangesDialog::on_dpi_changed(const wxRect& suggested_rect)
void UnsavedChangesDialog::on_sys_color_changed() void UnsavedChangesDialog::on_sys_color_changed()
{ {
for (auto btn : { m_save_btn, m_move_btn, m_continue_btn } ) for (auto btn : { m_save_btn, m_transfer_btn, m_discard_btn } )
btn->msw_rescale(); btn->msw_rescale();
// msw_rescale updates just icons, so use it // msw_rescale updates just icons, so use it
m_tree_model->Rescale(); m_tree_model->Rescale();

View File

@ -192,10 +192,11 @@ class UnsavedChangesDialog : public DPIDialog
UnsavedChangesModel* m_tree_model { nullptr }; UnsavedChangesModel* m_tree_model { nullptr };
ScalableButton* m_save_btn { nullptr }; ScalableButton* m_save_btn { nullptr };
ScalableButton* m_move_btn { nullptr }; ScalableButton* m_transfer_btn { nullptr };
ScalableButton* m_continue_btn { nullptr }; ScalableButton* m_discard_btn { nullptr };
wxStaticText* m_action_line { nullptr }; wxStaticText* m_action_line { nullptr };
wxStaticText* m_info_line { nullptr }; wxStaticText* m_info_line { nullptr };
wxCheckBox* m_remember_choice { nullptr };
bool m_empty_selection { false }; bool m_empty_selection { false };
bool m_has_long_strings { false }; bool m_has_long_strings { false };
@ -203,13 +204,19 @@ class UnsavedChangesDialog : public DPIDialog
int m_move_btn_id { wxID_ANY }; int m_move_btn_id { wxID_ANY };
int m_continue_btn_id { wxID_ANY }; int m_continue_btn_id { wxID_ANY };
std::string m_app_config_key;
enum class Action { enum class Action {
Undef, Undef,
Save, Transfer,
Move, Discard,
Continue Save
}; };
static constexpr char ActTransfer[] = "transfer";
static constexpr char ActDiscard[] = "discard";
static constexpr char ActSave[] = "save";
// selected action after Dialog closing // selected action after Dialog closing
Action m_exit_action {Action::Undef}; Action m_exit_action {Action::Undef};
@ -244,12 +251,13 @@ public:
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 = "");
void update_config(Action action);
void close(Action action); void close(Action action);
void save_and_close(PresetCollection* dependent_presets); void save(PresetCollection* dependent_presets);
bool save_preset() const { return m_exit_action == Action::Save; } bool save_preset() const { return m_exit_action == Action::Save; }
bool move_preset() const { return m_exit_action == Action::Move; } bool transfer_changes() const { return m_exit_action == Action::Transfer; }
bool just_continue() const { return m_exit_action == Action::Continue; } bool discard() const { return m_exit_action == Action::Discard; }
// get full bundle of preset names and types for saving // get full bundle of preset names and types for saving
const std::vector<std::pair<std::string, Preset::Type>>& get_names_and_types() { return names_and_types; } const std::vector<std::pair<std::string, Preset::Type>>& get_names_and_types() { return names_and_types; }

View File

@ -787,10 +787,12 @@ ScalableButton::ScalableButton( wxWindow * parent,
const wxSize& size /* = wxDefaultSize*/, const wxSize& size /* = wxDefaultSize*/,
const wxPoint& pos /* = wxDefaultPosition*/, const wxPoint& pos /* = wxDefaultPosition*/,
long style /*= wxBU_EXACTFIT | wxNO_BORDER*/, long style /*= wxBU_EXACTFIT | wxNO_BORDER*/,
bool use_default_disabled_bitmap/* = false*/) : bool use_default_disabled_bitmap/* = false*/,
int bmp_px_cnt/* = 16*/) :
m_parent(parent), m_parent(parent),
m_current_icon_name(icon_name), m_current_icon_name(icon_name),
m_use_default_disabled_bitmap (use_default_disabled_bitmap) m_use_default_disabled_bitmap (use_default_disabled_bitmap),
m_px_cnt(bmp_px_cnt)
{ {
Create(parent, id, label, pos, size, style); Create(parent, id, label, pos, size, style);
#ifdef __WXMSW__ #ifdef __WXMSW__
@ -798,7 +800,7 @@ ScalableButton::ScalableButton( wxWindow * parent,
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif // __WXMSW__ #endif // __WXMSW__
SetBitmap(create_scaled_bitmap(icon_name, parent)); SetBitmap(create_scaled_bitmap(icon_name, parent, m_px_cnt));
if (m_use_default_disabled_bitmap) if (m_use_default_disabled_bitmap)
SetBitmapDisabled(create_scaled_bitmap(m_current_icon_name, m_parent, m_px_cnt, true)); SetBitmapDisabled(create_scaled_bitmap(m_current_icon_name, m_parent, m_px_cnt, true));

View File

@ -210,7 +210,8 @@ public:
const wxSize& size = wxDefaultSize, const wxSize& size = wxDefaultSize,
const wxPoint& pos = wxDefaultPosition, const wxPoint& pos = wxDefaultPosition,
long style = wxBU_EXACTFIT | wxNO_BORDER, long style = wxBU_EXACTFIT | wxNO_BORDER,
bool use_default_disabled_bitmap = false); bool use_default_disabled_bitmap = false,
int bmp_px_cnt = 16);
ScalableButton( ScalableButton(
wxWindow * parent, wxWindow * parent,