Fixed non-consistency of the selection

This commit is contained in:
YuSanka 2019-04-04 15:07:54 +02:00
parent d806e8e5e1
commit 09054a0bc9
2 changed files with 100 additions and 51 deletions

View File

@ -89,7 +89,24 @@ ObjectList::ObjectList(wxWindow* parent) :
// manipulator cache with the following call to selection_changed() // manipulator cache with the following call to selection_changed()
wxGetApp().obj_manipul()->emulate_kill_focus(); wxGetApp().obj_manipul()->emulate_kill_focus();
#endif // __APPLE__ #endif // __APPLE__
/* For multiple selection with pressed SHIFT,
* event.GetItem() returns value of a first item in selection list
* instead of real last clicked item.
* So, let check last selected item in such strange way
*/
if (wxGetKeyState(WXK_SHIFT))
{
wxDataViewItemArray sels;
GetSelections(sels);
if (sels.front() == m_last_selected_item)
m_last_selected_item = sels.back();
else
m_last_selected_item = event.GetItem(); m_last_selected_item = event.GetItem();
}
else
m_last_selected_item = event.GetItem();
selection_changed(); selection_changed();
#ifndef __WXMSW__ #ifndef __WXMSW__
set_tooltip_for_item(get_mouse_position_in_control()); set_tooltip_for_item(get_mouse_position_in_control());
@ -511,7 +528,7 @@ void ObjectList::key_event(wxKeyEvent& event)
printf("WXK_BACK\n"); printf("WXK_BACK\n");
remove(); remove();
} }
else if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_SHIFT)) else if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_CONTROL/*WXK_SHIFT*/))
select_item_all_children(); select_item_all_children();
else else
event.Skip(); event.Skip();
@ -2183,11 +2200,10 @@ void ObjectList::select_item_all_children()
// update selection mode for non-multiple selection // update selection mode for non-multiple selection
void ObjectList::update_selection_mode() void ObjectList::update_selection_mode()
{ {
m_last_selected_item = wxDataViewItem(0);
// All items are unselected // All items are unselected
if (!GetSelection()) if (!GetSelection())
{ {
m_last_selected_item = wxDataViewItem(0);
m_selection_mode = smUndef; m_selection_mode = smUndef;
return; return;
} }
@ -2198,33 +2214,55 @@ void ObjectList::update_selection_mode()
} }
// check last selected item. If is it possible to select it // check last selected item. If is it possible to select it
bool ObjectList::check_last_selection() bool ObjectList::check_last_selection(wxString& msg_str)
{ {
if (!m_last_selected_item) if (!m_last_selected_item)
return true; return true;
const bool is_shift_pressed = wxGetKeyState(WXK_SHIFT);
/* We can't mix Parts and Objects/Instances. /* We can't mix Parts and Objects/Instances.
* So, unselect last selected item and show information about it * So, show information about it
*/ */
const ItemType type = m_objects_model->GetItemType(m_last_selected_item); const ItemType type = m_objects_model->GetItemType(m_last_selected_item);
if (type & itSettings ||
// check a case of a selection of the Parts from different Objects
bool impossible_multipart_selection = false;
if (type & itVolume && m_selection_mode == smVolume)
{
wxDataViewItemArray sels;
GetSelections(sels);
for (const auto& sel: sels)
if (sel != m_last_selected_item &&
m_objects_model->GetParent(sel) != m_objects_model->GetParent(m_last_selected_item))
{
impossible_multipart_selection = true;
break;
}
}
if (impossible_multipart_selection ||
type & itSettings ||
type & itVolume && m_selection_mode == smInstance || type & itVolume && m_selection_mode == smInstance ||
!(type & itVolume) && m_selection_mode == smVolume) !(type & itVolume) && m_selection_mode == smVolume)
{ {
Unselect(m_last_selected_item);
// Inform user why selection isn't complited // Inform user why selection isn't complited
const wxString item_type = m_selection_mode == smInstance ? _(L("Object or Instance")) : _(L("Part")); const wxString item_type = m_selection_mode == smInstance ? _(L("Object or Instance")) : _(L("Part"));
const wxString msg_str = wxString::Format(_(L("You started your selection with %s Item.")) + "\n" + msg_str = wxString::Format( _(L("Unsupported selection")) + "\n\n" +
_(L("In this mode you can select only another %s Items%s")), item_type, item_type, _(L("You started your selection with %s Item.")) + "\n" +
m_selection_mode == smInstance ? "." : " " + _(L("of a current Object"))); _(L("In this mode you can select only other %s Items%s")),
item_type, item_type,
m_selection_mode == smInstance ? "." :
" " + _(L("of a current Object")));
wxMessageDialog dialog(this, _(L("Unsupported selection")) + "\n\n" + msg_str, // Unselect last selected item, if selection is without SHIFT
_(L("Info")), wxICON_INFORMATION); if (!is_shift_pressed) {
dialog.ShowModal(); Unselect(m_last_selected_item);
show_info(this, msg_str, _(L("Info")));
}
return false; return is_shift_pressed;
} }
return true; return true;
@ -2237,7 +2275,8 @@ void ObjectList::fix_multiselection_conflicts()
return; return;
} }
if (!check_last_selection()) wxString msg_string;
if (!check_last_selection(msg_string))
return; return;
m_prevent_list_events = true; m_prevent_list_events = true;
@ -2245,9 +2284,27 @@ void ObjectList::fix_multiselection_conflicts()
wxDataViewItemArray sels; wxDataViewItemArray sels;
GetSelections(sels); GetSelections(sels);
m_selection_mode = smInstance; if (m_selection_mode == smVolume)
{
// identify correct parent of the initial selected item
const wxDataViewItem& parent = m_objects_model->GetParent(m_last_selected_item == sels.front() ? sels.back() : sels.front());
for (const auto item : sels) { sels.clear();
wxDataViewItemArray children; // selected volumes from current parent
m_objects_model->GetChildren(parent, children);
for (const auto child : children)
if (IsSelected(child) && m_objects_model->GetItemType(child)&itVolume)
sels.Add(child);
// If some part is selected, unselect all items except of selected parts of the current object
UnselectAll();
SetSelections(sels);
}
else
{
for (const auto item : sels)
{
if (!IsSelected(item)) // if this item is unselected now (from previous actions) if (!IsSelected(item)) // if this item is unselected now (from previous actions)
continue; continue;
@ -2267,27 +2324,19 @@ void ObjectList::fix_multiselection_conflicts()
Unselect(unsel_item); Unselect(unsel_item);
} }
if (m_objects_model->GetItemType(item) == itVolume) if (m_objects_model->GetItemType(item) & itVolume)
{ Unselect(item);
// If some part is selected, unselect all items except of selected parts of the current object
sels.clear();
wxDataViewItemArray children; // selected volumes from current parent m_selection_mode = smInstance;
m_objects_model->GetChildren(parent, children);
for (const auto child : children)
{
if (IsSelected(child) && m_objects_model->GetItemType(child)&itVolume)
sels.Add(child);
}
UnselectAll();
SetSelections(sels);
m_selection_mode = smVolume;
break;
} }
} }
if (!msg_string.IsEmpty())
show_info(this, msg_string, _(L("Info")));
if (!IsSelected(m_last_selected_item))
m_last_selected_item = wxDataViewItem(0);
m_prevent_list_events = false; m_prevent_list_events = false;
} }

View File

@ -267,7 +267,7 @@ public:
void select_all(); void select_all();
void select_item_all_children(); void select_item_all_children();
void update_selection_mode(); void update_selection_mode();
bool check_last_selection(); bool check_last_selection(wxString& msg_str);
// correct current selections to avoid of the possible conflicts // correct current selections to avoid of the possible conflicts
void fix_multiselection_conflicts(); void fix_multiselection_conflicts();