mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 04:02:52 -06:00 
			
		
		
		
	Unsaved Changes : implemented "move" and improved "save"
UnsavedChangesDialog : some code refactoring SavePresetDialog : processed empty name for the preset
This commit is contained in:
		
							parent
							
								
									491e7b16f9
								
							
						
					
					
						commit
						d7176c64bd
					
				
					 5 changed files with 90 additions and 84 deletions
				
			
		|  | @ -1123,10 +1123,12 @@ void SavePresetDialog::Item::update() | |||
|         info_line = _L("Cannot overwrite a system profile."); | ||||
|         m_valid_type = NoValid; | ||||
|     } | ||||
| 
 | ||||
|     if (m_valid_type == Valid && existing && (existing->is_external)) { | ||||
|         info_line = _L("Cannot overwrite an external profile."); | ||||
|         m_valid_type = NoValid; | ||||
|     } | ||||
| 
 | ||||
|     if (m_valid_type == Valid && existing && m_preset_name != m_presets->get_selected_preset_name()) | ||||
|     { | ||||
|         info_line = from_u8((boost::format(_u8L("Preset with name \"%1%\" already exists.")) % m_preset_name).str()) + "\n" + | ||||
|  | @ -1134,6 +1136,11 @@ void SavePresetDialog::Item::update() | |||
|         m_valid_type = Warning; | ||||
|     } | ||||
| 
 | ||||
|     if (m_valid_type == Valid && m_preset_name.empty()) { | ||||
|         info_line = _L("The empty name is not available."); | ||||
|         m_valid_type = NoValid; | ||||
|     } | ||||
| 
 | ||||
|     m_valid_label->SetLabel(info_line); | ||||
|     m_valid_label->Show(!info_line.IsEmpty()); | ||||
| 
 | ||||
|  |  | |||
|  | @ -3124,6 +3124,12 @@ void Tab::select_preset(std::string preset_name, bool delete_current /*=false*/, | |||
|                 m_dependent_tabs = { Preset::Type::TYPE_SLA_PRINT, Preset::Type::TYPE_SLA_MATERIAL }; | ||||
|         } | ||||
| 
 | ||||
|         // check if there is something in the cache to move to the new selected preset
 | ||||
|         if (!m_cache_config.empty()) { | ||||
|             m_presets->get_edited_preset().config.apply(m_cache_config); | ||||
|             m_cache_config.clear(); | ||||
|         } | ||||
| 
 | ||||
|         load_current_preset(); | ||||
|     } | ||||
| } | ||||
|  | @ -3134,11 +3140,10 @@ bool Tab::may_discard_current_dirty_preset(PresetCollection* presets /*= nullptr | |||
| { | ||||
|     if (presets == nullptr) presets = m_presets; | ||||
| 
 | ||||
|     UnsavedChangesDialog dlg(m_type, new_printer_name); | ||||
|     UnsavedChangesDialog dlg(m_type, presets, new_printer_name); | ||||
|     if (dlg.ShowModal() == wxID_CANCEL) | ||||
|         return false; | ||||
|     if (dlg.just_continue()) | ||||
|         return true; | ||||
| 
 | ||||
|     if (dlg.save_preset())  // save selected changes
 | ||||
|     { | ||||
|         std::vector<std::string> unselected_options = dlg.get_unselected_options(); | ||||
|  | @ -3147,7 +3152,7 @@ bool Tab::may_discard_current_dirty_preset(PresetCollection* presets /*= nullptr | |||
| 
 | ||||
|         // for system/default/external presets we should take an edited name
 | ||||
|         if (preset.is_system || preset.is_default || preset.is_external) { | ||||
|             SavePresetDialog save_dlg(m_type, _CTX_utf8(L_CONTEXT("Copy", "PresetName"), "PresetName")); | ||||
|             SavePresetDialog save_dlg(preset.type, _CTX_utf8(L_CONTEXT("Copy", "PresetName"), "PresetName")); | ||||
|             if (save_dlg.ShowModal() != wxID_OK) | ||||
|                 return false; | ||||
|             name = save_dlg.get_name(); | ||||
|  | @ -3157,56 +3162,35 @@ bool Tab::may_discard_current_dirty_preset(PresetCollection* presets /*= nullptr | |||
|         if (!unselected_options.empty()) | ||||
|         { | ||||
|             DynamicPrintConfig& old_config = presets->get_selected_preset().config; | ||||
| 
 | ||||
|             // revert unselected options to the old values
 | ||||
|             for (const std::string& opt_key : unselected_options) | ||||
|                 m_config->set_key_value(opt_key, old_config.option(opt_key)->clone());             | ||||
|                 presets->get_edited_preset().config.set_key_value(opt_key, old_config.option(opt_key)->clone()); | ||||
|         } | ||||
| 
 | ||||
|         save_preset(name); | ||||
|         return true; | ||||
|     } | ||||
|     if (dlg.move_preset()) | ||||
|         // move selected changes
 | ||||
|         return false; | ||||
|         if (m_type == presets->type()) // save changes for the current preset        
 | ||||
|             save_preset(name); | ||||
|         else // save changes for dependent preset
 | ||||
|         { | ||||
|             // Save the preset into Slic3r::data_dir / presets / section_name / preset_name.ini
 | ||||
|             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); | ||||
| 
 | ||||
|     return false; | ||||
| /*
 | ||||
|     // Display a dialog showing the dirty options in a human readable form.
 | ||||
|     const Preset& old_preset = presets->get_edited_preset(); | ||||
|     std::string   type_name  = presets->name(); | ||||
|     wxString      tab        = "          "; | ||||
|     wxString      name       = old_preset.is_default ? | ||||
|         from_u8((boost::format(_utf8(L("Default preset (%s)"))) % _utf8(type_name)).str()) : | ||||
|         from_u8((boost::format(_utf8(L("Preset (%s)"))) % _utf8(type_name)).str()) + "\n" + tab + old_preset.name; | ||||
|             /* If filament preset is saved for multi-material printer preset,
 | ||||
|              * there are cases when filament comboboxs are updated for old (non-modified) colors, | ||||
|              * but in full_config a filament_colors option aren't.*/ | ||||
|             if (presets->type() == Preset::TYPE_FILAMENT && wxGetApp().extruders_edited_cnt() > 1) | ||||
|                 wxGetApp().plater()->force_filament_colors_update(); | ||||
|         } | ||||
|     } | ||||
|     else if (dlg.move_preset()) // move selected changes
 | ||||
|     { | ||||
|         // copy selected options to the cache from edited preset
 | ||||
|         m_cache_config.apply_only(*m_config, dlg.get_selected_options()); | ||||
|     } | ||||
| 
 | ||||
|     // Collect descriptions of the dirty options.
 | ||||
|     wxString changes; | ||||
|     for (const std::string &opt_key : presets->current_dirty_options()) { | ||||
|         const ConfigOptionDef &opt = m_config->def()->options.at(opt_key); | ||||
|         wxString name = ""; | ||||
|         if (! opt.category.empty()) | ||||
|             name += _(opt.category) + " > "; | ||||
|         name += !opt.full_label.empty() ? | ||||
|                 _(opt.full_label) : | ||||
|                 _(opt.label); | ||||
|         changes += tab + (name) + "\n"; | ||||
|     } | ||||
|     // Show a confirmation dialog with the list of dirty options.
 | ||||
|     wxString message = name + "\n\n"; | ||||
|     if (new_printer_name.empty()) | ||||
|         message += _(L("has the following unsaved changes:")); | ||||
|     else { | ||||
|         message += (m_type == Slic3r::Preset::TYPE_PRINTER) ? | ||||
|                 _(L("is not compatible with printer")) : | ||||
|                 _(L("is not compatible with print profile")); | ||||
|         message += wxString("\n") + tab + from_u8(new_printer_name) + "\n\n"; | ||||
|         message += _(L("and it has the following unsaved changes:")); | ||||
|     } | ||||
|     wxMessageDialog confirm(parent(), | ||||
|         message + "\n" + changes + "\n\n" + _(L("Discard changes and continue anyway?")), | ||||
|         _(L("Unsaved Changes")), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION); | ||||
|     return confirm.ShowModal() == wxID_YES; | ||||
|     */ | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| // If we are switching from the FFF-preset to the SLA, we should to control the printed objects if they have a part(s).
 | ||||
|  |  | |||
|  | @ -236,6 +236,7 @@ public: | |||
| 	bool				m_show_btn_incompatible_presets = false; | ||||
| 	PresetCollection*	m_presets; | ||||
| 	DynamicPrintConfig*	m_config; | ||||
| 	DynamicPrintConfig 	m_cache_config; | ||||
| 	ogStaticText*		m_parent_preset_description_line; | ||||
| 	ScalableButton*		m_detach_preset_btn	= nullptr; | ||||
| 
 | ||||
|  |  | |||
|  | @ -514,7 +514,7 @@ void UnsavedChangesModel::Rescale() | |||
| //          UnsavedChangesDialog
 | ||||
| //------------------------------------------
 | ||||
| 
 | ||||
| UnsavedChangesDialog::UnsavedChangesDialog(Preset::Type type, 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) | ||||
| { | ||||
|     wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); | ||||
|  | @ -530,6 +530,9 @@ UnsavedChangesDialog::UnsavedChangesDialog(Preset::Type type, const std::string& | |||
|     int border = 10; | ||||
|     int em = em_unit(); | ||||
| 
 | ||||
|     m_action_line = new wxStaticText(this, wxID_ANY, ""); | ||||
|     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_model = new UnsavedChangesModel(this); | ||||
|     m_tree->AssociateModel(m_tree_model); | ||||
|  | @ -563,34 +566,22 @@ UnsavedChangesDialog::UnsavedChangesDialog(Preset::Type type, const std::string& | |||
|     // Add Buttons 
 | ||||
|     wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxCANCEL); | ||||
| 
 | ||||
|     Tab* tab = wxGetApp().get_tab(type); | ||||
|     assert(tab); | ||||
|     PresetCollection* presets = tab->get_presets(); | ||||
|     auto add_btn = [this, buttons](ScalableButton** btn, int& btn_id, const std::string& icon_name, Action close_act, int idx, bool process_enable = true) | ||||
|     { | ||||
|         *btn = new ScalableButton(this, btn_id = NewControlId(), icon_name, "", wxDefaultSize, wxDefaultPosition, wxBORDER_DEFAULT, true); | ||||
|         buttons->Insert(idx, *btn, 0, wxLEFT, 5); | ||||
| 
 | ||||
|     wxString label= from_u8((boost::format(_u8L("Save selected to preset: %1%"))% ("\"" + presets->get_selected_preset().name + "\"")).str()); | ||||
|     m_save_btn = new ScalableButton(this, m_save_btn_id = NewControlId(), "save", label, wxDefaultSize, wxDefaultPosition, wxBORDER_DEFAULT, true); | ||||
|     buttons->Insert(0, m_save_btn, 0, wxLEFT, 5); | ||||
|         (*btn)->Bind(wxEVT_BUTTON, [this, close_act](wxEvent&) { close(close_act); }); | ||||
|         if (process_enable) | ||||
|             (*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(); }); | ||||
|     }; | ||||
| 
 | ||||
|     m_save_btn->Bind(wxEVT_BUTTON,      [this](wxEvent&)                { close(Action::Save); }); | ||||
|     m_save_btn->Bind(wxEVT_UPDATE_UI,   [this](wxUpdateUIEvent& evt)    { evt.Enable(!m_empty_selection); }); | ||||
|     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_LEAVE_WINDOW,[this         ](wxMouseEvent& e){ show_info_line(Action::Undef); e.Skip(); }); | ||||
| 
 | ||||
|     label = from_u8((boost::format(_u8L("Move selected to preset: %1%"))% ("\"" + from_u8(new_selected_preset) + "\"")).str()); | ||||
|     m_move_btn = new ScalableButton(this, m_move_btn_id = NewControlId(), "paste_menu", label, wxDefaultSize, wxDefaultPosition, wxBORDER_DEFAULT, true); | ||||
|     buttons->Insert(1, m_move_btn, 0, wxLEFT, 5); | ||||
| 
 | ||||
|     m_move_btn->Bind(wxEVT_BUTTON,      [this](wxEvent&)                            { close(Action::Move); }); | ||||
|     m_move_btn->Bind(wxEVT_UPDATE_UI,   [this](wxUpdateUIEvent& evt)                { evt.Enable(!m_empty_selection); }); | ||||
|     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_LEAVE_WINDOW,[this                     ](wxMouseEvent& e){ show_info_line(Action::Undef); e.Skip(); }); | ||||
| 
 | ||||
|     label = _L("Continue without changes"); | ||||
|     m_continue_btn = new ScalableButton(this, m_continue_btn_id = NewControlId(), "cross", label, wxDefaultSize, wxDefaultPosition, wxBORDER_DEFAULT, true); | ||||
|     buttons->Insert(2, m_continue_btn, 0, wxLEFT, 5); | ||||
|     m_continue_btn->Bind(wxEVT_BUTTON,      [this](wxEvent&)       { close(Action::Continue); }); | ||||
|     m_continue_btn->Bind(wxEVT_ENTER_WINDOW,[this](wxMouseEvent& e){ show_info_line(Action::Continue); e.Skip(); }); | ||||
|     m_continue_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++); | ||||
|     if (type == dependent_presets->type()) | ||||
|         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); | ||||
| 
 | ||||
|     m_info_line = new wxStaticText(this, wxID_ANY, ""); | ||||
|     m_info_line->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold()); | ||||
|  | @ -598,12 +589,12 @@ UnsavedChangesDialog::UnsavedChangesDialog(Preset::Type type, const std::string& | |||
| 
 | ||||
|     wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL); | ||||
| 
 | ||||
|     topSizer->Add(new wxStaticText(this, wxID_ANY, _L("There are unsaved changes for") + (": \"" + tab->title() + "\"")), 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_info_line,  0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, 2*border); | ||||
|     topSizer->Add(buttons,      0, wxEXPAND | wxALL, border); | ||||
| 
 | ||||
|     update(type); | ||||
|     update(type, dependent_presets, new_selected_preset); | ||||
| 
 | ||||
|     SetSizer(topSizer); | ||||
|     topSizer->SetSizeHints(this); | ||||
|  | @ -824,12 +815,34 @@ wxString UnsavedChangesDialog::get_short_string(wxString full_string) | |||
|     return full_string + dots; | ||||
| } | ||||
| 
 | ||||
| void UnsavedChangesDialog::update(Preset::Type type) | ||||
| void UnsavedChangesDialog::update(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset) | ||||
| { | ||||
|     Tab* tab = wxGetApp().get_tab(type); | ||||
|     assert(tab); | ||||
|     PresetCollection* presets = dependent_presets; | ||||
| 
 | ||||
|     // 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(); }); | ||||
|     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_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")); | ||||
| 
 | ||||
|     wxString action_msg; | ||||
|     if (type == dependent_presets->type()) { | ||||
|         action_msg = _L("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) + "\" "; | ||||
|         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())); | ||||
| 
 | ||||
|     PresetCollection* presets = tab->get_presets(); | ||||
|     // Display a dialog showing the dirty options in a human readable form.
 | ||||
|     const DynamicPrintConfig& old_config = presets->get_selected_preset().config; | ||||
|     const DynamicPrintConfig& new_config = presets->get_edited_preset().config; | ||||
|  |  | |||
|  | @ -193,6 +193,7 @@ class UnsavedChangesDialog : public DPIDialog | |||
|     ScalableButton*         m_save_btn      { nullptr }; | ||||
|     ScalableButton*         m_move_btn      { nullptr }; | ||||
|     ScalableButton*         m_continue_btn  { nullptr }; | ||||
|     wxStaticText*           m_action_line   { nullptr }; | ||||
|     wxStaticText*           m_info_line     { nullptr }; | ||||
| 
 | ||||
|     bool                    m_empty_selection   { false }; | ||||
|  | @ -226,12 +227,12 @@ class UnsavedChangesDialog : public DPIDialog | |||
|     std::map<wxDataViewItem, ItemData> m_items_map; | ||||
| 
 | ||||
| public: | ||||
|     UnsavedChangesDialog(Preset::Type type, const std::string& new_selected_preset); | ||||
|     UnsavedChangesDialog(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset); | ||||
|     ~UnsavedChangesDialog() {} | ||||
| 
 | ||||
|     wxString get_short_string(wxString full_string); | ||||
| 
 | ||||
|     void update(Preset::Type type); | ||||
|     void update(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset); | ||||
|     void item_value_changed(wxDataViewEvent &event); | ||||
|     void context_menu(wxDataViewEvent &event); | ||||
|     void show_info_line(Action action, std::string preset_name = ""); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 YuSanka
						YuSanka