Implement wxTreeCtrl::GetFirstChild() in terms of GetNextChild()

This makes the code slightly simpler, as there is just one function
instead of two, and also changes the meaning of the value stored in the
cookie parameter as a side effect: previously, it was the index of the
last retrieved item, while now it's the index of the next item to
retrieve.

The difference is not huge, but the latter is more usual and, more
importantly, avoids a stack overflow due to infinite recursion in the
treectrl sample, which assumed that cookie is never null after a
successful call to GetFirstChild(). The code in the sample is arguably
incorrect, as the cookie is supposed to be opaque, but it's still better
to avoid crashing, especially because similar code is almost certainly
present in user code if it was copied from the sample.
This commit is contained in:
Vadim Zeitlin
2019-06-29 20:07:41 +02:00
parent 21b2eef7e5
commit 2ce16cba08

View File

@@ -855,14 +855,8 @@ wxTreeItemId wxTreeCtrl::GetFirstChild(
wxTreeItemIdValue& cookie wxTreeItemIdValue& cookie
) const ) const
{ {
wxCHECK_MSG(item.IsOk(), wxTreeItemId(), "invalid tree item");
cookie = 0; cookie = 0;
QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); return GetNextChild(item, cookie);
return qTreeItem->childCount() > 0
? wxQtConvertTreeItem(qTreeItem->child(0))
: wxTreeItemId();
} }
wxTreeItemId wxTreeCtrl::GetNextChild( wxTreeItemId wxTreeCtrl::GetNextChild(
@@ -873,17 +867,17 @@ wxTreeItemId wxTreeCtrl::GetNextChild(
wxCHECK_MSG(item.IsOk(), wxTreeItemId(), "invalid tree item"); wxCHECK_MSG(item.IsOk(), wxTreeItemId(), "invalid tree item");
wxIntPtr currentIndex = reinterpret_cast<wxIntPtr>(cookie); wxIntPtr currentIndex = reinterpret_cast<wxIntPtr>(cookie);
++currentIndex;
const QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); const QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item);
wxTreeItemId childItem;
if ( currentIndex < qTreeItem->childCount() ) if ( currentIndex < qTreeItem->childCount() )
{ {
childItem = wxQtConvertTreeItem(qTreeItem->child(currentIndex++));
cookie = reinterpret_cast<wxTreeItemIdValue>(currentIndex); cookie = reinterpret_cast<wxTreeItemIdValue>(currentIndex);
return wxQtConvertTreeItem(qTreeItem->child(currentIndex));
} }
return wxTreeItemId(); return childItem;
} }
wxTreeItemId wxTreeCtrl::GetLastChild(const wxTreeItemId& item) const wxTreeItemId wxTreeCtrl::GetLastChild(const wxTreeItemId& item) const