diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index e9180d39ae..cb031a8d0f 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -313,7 +313,7 @@ void ObjectList::update_extruder_in_config(const wxDataViewItem& item) wxGetApp().plater()->update(); } -void ObjectList::update_name_in_model(const wxDataViewItem& item) +void ObjectList::update_name_in_model(const wxDataViewItem& item) const { const int obj_idx = m_objects_model->GetObjectIdByItem(item); if (obj_idx < 0) return; @@ -958,8 +958,18 @@ wxMenuItem* ObjectList::append_menu_item_instance_to_object(wxMenu* menu) [this](wxCommandEvent&) { split_instances(); }, "", menu); } +wxMenuItem* ObjectList::append_menu_item_rename(wxMenu* menu) +{ + return append_menu_item(menu, wxID_ANY, _(L("Rename")), "", + [this](wxCommandEvent&) { rename_item(); }, "", menu); +} + void ObjectList::create_object_popupmenu(wxMenu *menu) { +#ifdef __WXOSX__ + append_menu_item_rename(menu); +#endif // __WXOSX__ + // Split object to parts m_menu_item_split = append_menu_item_split(menu); menu->AppendSeparator(); @@ -980,6 +990,10 @@ void ObjectList::create_sla_object_popupmenu(wxMenu *menu) void ObjectList::create_part_popupmenu(wxMenu *menu) { +#ifdef __WXOSX__ + append_menu_item_rename(menu); +#endif // __WXOSX__ + m_menu_item_split_part = append_menu_item_split(menu); // Append change part type @@ -2055,6 +2069,48 @@ void ObjectList::split_instances() instances_to_separated_object(obj_idx, inst_idxs); } +void ObjectList::rename_item() +{ + const wxDataViewItem item = GetSelection(); + if (!item || !(m_objects_model->GetItemType(item) & (itVolume | itObject))) + return ; + + const wxString new_name = wxGetTextFromUser(_(L("Enter new name"))+":", _(L("Renaming")), + m_objects_model->GetName(item), this); + + bool is_unusable_symbol = false; + std::string chosen_name = Slic3r::normalize_utf8_nfc(new_name.ToUTF8()); + const char* unusable_symbols = "<>:/\\|?*\""; + for (size_t i = 0; i < std::strlen(unusable_symbols); i++) { + if (chosen_name.find_first_of(unusable_symbols[i]) != std::string::npos) { + is_unusable_symbol = true; + } + } + + if (is_unusable_symbol) { + show_error(this, _(L("The supplied name is not valid;")) + "\n" + + _(L("the following characters are not allowed:")) + " <>:/\\|?*\""); + return; + } + + // The icon can't be edited so get its old value and reuse it. + wxVariant valueOld; + m_objects_model->GetValue(valueOld, item, 0); + + PrusaDataViewBitmapText bmpText; + bmpText << valueOld; + + // But replace the text with the value entered by user. + bmpText.SetText(new_name); + + wxVariant value; + value << bmpText; + m_objects_model->SetValue(value, item, 0); + m_objects_model->ItemChanged(item); + + update_name_in_model(item); +} + void ObjectList::ItemValueChanged(wxDataViewEvent &event) { if (event.GetColumn() == 0) diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 741fa37415..86e2167ddc 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -161,7 +161,7 @@ public: // update extruder in current config void update_extruder_in_config(const wxDataViewItem& item); // update changed name in the object model - void update_name_in_model(const wxDataViewItem& item); + void update_name_in_model(const wxDataViewItem& item) const; void update_extruder_values_for_items(const int max_extruder); void init_icons(); @@ -182,6 +182,7 @@ public: wxMenuItem* append_menu_item_settings(wxMenu* menu); wxMenuItem* append_menu_item_change_type(wxMenu* menu); wxMenuItem* append_menu_item_instance_to_object(wxMenu* menu); + wxMenuItem* append_menu_item_rename(wxMenu* menu); void create_object_popupmenu(wxMenu *menu); void create_sla_object_popupmenu(wxMenu*menu); void create_part_popupmenu(wxMenu*menu); @@ -263,6 +264,7 @@ public: void instances_to_separated_object(const int obj_idx, const std::set& inst_idx); void split_instances(); + void rename_item(); private: void OnChar(wxKeyEvent& event);