Fixed non-consistency of the selection
This commit is contained in:
parent
d806e8e5e1
commit
09054a0bc9
@ -89,7 +89,24 @@ ObjectList::ObjectList(wxWindow* parent) :
|
||||
// manipulator cache with the following call to selection_changed()
|
||||
wxGetApp().obj_manipul()->emulate_kill_focus();
|
||||
#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();
|
||||
}
|
||||
else
|
||||
m_last_selected_item = event.GetItem();
|
||||
|
||||
selection_changed();
|
||||
#ifndef __WXMSW__
|
||||
set_tooltip_for_item(get_mouse_position_in_control());
|
||||
@ -511,7 +528,7 @@ void ObjectList::key_event(wxKeyEvent& event)
|
||||
printf("WXK_BACK\n");
|
||||
remove();
|
||||
}
|
||||
else if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_SHIFT))
|
||||
else if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_CONTROL/*WXK_SHIFT*/))
|
||||
select_item_all_children();
|
||||
else
|
||||
event.Skip();
|
||||
@ -2183,11 +2200,10 @@ void ObjectList::select_item_all_children()
|
||||
// update selection mode for non-multiple selection
|
||||
void ObjectList::update_selection_mode()
|
||||
{
|
||||
m_last_selected_item = wxDataViewItem(0);
|
||||
|
||||
// All items are unselected
|
||||
if (!GetSelection())
|
||||
{
|
||||
m_last_selected_item = wxDataViewItem(0);
|
||||
m_selection_mode = smUndef;
|
||||
return;
|
||||
}
|
||||
@ -2198,33 +2214,55 @@ void ObjectList::update_selection_mode()
|
||||
}
|
||||
|
||||
// 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)
|
||||
return true;
|
||||
|
||||
const bool is_shift_pressed = wxGetKeyState(WXK_SHIFT);
|
||||
|
||||
/* 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);
|
||||
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 == smVolume)
|
||||
{
|
||||
Unselect(m_last_selected_item);
|
||||
|
||||
// Inform user why selection isn't complited
|
||||
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" +
|
||||
_(L("In this mode you can select only another %s Items%s")), item_type, item_type,
|
||||
m_selection_mode == smInstance ? "." : " " + _(L("of a current Object")));
|
||||
msg_str = wxString::Format( _(L("Unsupported selection")) + "\n\n" +
|
||||
_(L("You started your selection with %s Item.")) + "\n" +
|
||||
_(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,
|
||||
_(L("Info")), wxICON_INFORMATION);
|
||||
dialog.ShowModal();
|
||||
// Unselect last selected item, if selection is without SHIFT
|
||||
if (!is_shift_pressed) {
|
||||
Unselect(m_last_selected_item);
|
||||
show_info(this, msg_str, _(L("Info")));
|
||||
}
|
||||
|
||||
return false;
|
||||
return is_shift_pressed;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -2237,7 +2275,8 @@ void ObjectList::fix_multiselection_conflicts()
|
||||
return;
|
||||
}
|
||||
|
||||
if (!check_last_selection())
|
||||
wxString msg_string;
|
||||
if (!check_last_selection(msg_string))
|
||||
return;
|
||||
|
||||
m_prevent_list_events = true;
|
||||
@ -2245,9 +2284,27 @@ void ObjectList::fix_multiselection_conflicts()
|
||||
wxDataViewItemArray 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)
|
||||
continue;
|
||||
|
||||
@ -2267,27 +2324,19 @@ void ObjectList::fix_multiselection_conflicts()
|
||||
Unselect(unsel_item);
|
||||
}
|
||||
|
||||
if (m_objects_model->GetItemType(item) == itVolume)
|
||||
{
|
||||
// If some part is selected, unselect all items except of selected parts of the current object
|
||||
sels.clear();
|
||||
if (m_objects_model->GetItemType(item) & itVolume)
|
||||
Unselect(item);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
UnselectAll();
|
||||
SetSelections(sels);
|
||||
|
||||
m_selection_mode = smVolume;
|
||||
break;
|
||||
m_selection_mode = smInstance;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -267,7 +267,7 @@ public:
|
||||
void select_all();
|
||||
void select_item_all_children();
|
||||
void update_selection_mode();
|
||||
bool check_last_selection();
|
||||
bool check_last_selection(wxString& msg_str);
|
||||
// correct current selections to avoid of the possible conflicts
|
||||
void fix_multiselection_conflicts();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user