Fix wxDataViewCtrl::GetItemRect() for collapsed items

Calling GetItemRect() for an item which was not currently visible
because its parent was collapsed resulted in silently returning the
value for a wrong value before the recent fix to GetRowByItem() and in
a crash after it because GetTreeNodeByRow() returned null when passed
invalid row index.

Fix this by explicitly checking whether the item is shown and just
returning an empty rectangle instead.

Also document this behaviour and add a unit test for it.
This commit is contained in:
Vadim Zeitlin
2018-11-04 17:12:08 +01:00
parent 31c49caab5
commit ada5de3d0d
3 changed files with 34 additions and 3 deletions

View File

@@ -1446,8 +1446,13 @@ public:
int GetIndent() const;
/**
Returns item rectangle. Coordinates of the rectangle are specified in
wxDataViewCtrl client area coordinates.
Returns item rectangle.
If item is not currently visible because its parent is collapsed,
return an empty rectangle.
Coordinates of the rectangle are specified in wxDataViewCtrl client
area coordinates.
@param item
A valid item.

View File

@@ -3809,10 +3809,16 @@ wxRect wxDataViewMainWindow::GetItemRect( const wxDataViewItem & item,
xpos = 0;
}
const int row = GetRowByItem(item);
if ( row == -1 )
{
// This means the row is currently not visible at all.
return wxRect();
}
// we have to take an expander column into account and compute its indentation
// to get the correct x position where the actual text is
int indent = 0;
int row = GetRowByItem(item);
if (!IsList() &&
(column == 0 || GetExpanderColumnOrFirstOne(GetOwner()) == column) )
{

View File

@@ -198,4 +198,24 @@ TEST_CASE_METHOD(SingleSelectDataViewCtrlTestCase,
CHECK( !m_dvc->IsExpanded(m_child2) );
}
TEST_CASE_METHOD(SingleSelectDataViewCtrlTestCase,
"wxDVC::GetItemRect",
"[wxDataViewCtrl][item]")
{
#ifdef __WXGTK__
WARN("Disabled under GTK because GetItemRect() is not implemented");
#else
const wxRect rect1 = m_dvc->GetItemRect(m_child1);
const wxRect rect2 = m_dvc->GetItemRect(m_child2);
CHECK( rect1.x == rect2.x );
CHECK( rect1.width == rect2.width );
CHECK( rect1.height == rect2.height );
CHECK( rect1.y < rect2.y );
const wxRect rectNotShown = m_dvc->GetItemRect(m_grandchild);
CHECK( rectNotShown == wxRect() );
#endif
}
#endif //wxUSE_DATAVIEWCTRL