+void wxTreeCtrl::SetItemText(const wxTreeItemId& item, const wxString& text)
+{
+ wxTreeViewItem tvItem(item, TVIF_TEXT);
+ tvItem.pszText = (wxChar *)text.c_str(); // conversion is ok
+ DoSetItem(&tvItem);
+}
+
+int wxTreeCtrl::DoGetItemImageFromData(const wxTreeItemId& item,
+ wxTreeItemIcon which) const
+{
+ wxTreeViewItem tvItem(item, TVIF_PARAM);
+ if ( !DoGetItem(&tvItem) )
+ {
+ return -1;
+ }
+
+ return ((wxTreeItemIndirectData *)tvItem.lParam)->GetImage(which);
+}
+
+void wxTreeCtrl::DoSetItemImageFromData(const wxTreeItemId& item,
+ int image,
+ wxTreeItemIcon which) const
+{
+ wxTreeViewItem tvItem(item, TVIF_PARAM);
+ if ( !DoGetItem(&tvItem) )
+ {
+ return;
+ }
+
+ wxTreeItemIndirectData *data = ((wxTreeItemIndirectData *)tvItem.lParam);
+
+ data->SetImage(image, which);
+
+ // make sure that we have selected images as well
+ if ( which == wxTreeItemIcon_Normal &&
+ !data->HasImage(wxTreeItemIcon_Selected) )
+ {
+ data->SetImage(image, wxTreeItemIcon_Selected);
+ }
+
+ if ( which == wxTreeItemIcon_Expanded &&
+ !data->HasImage(wxTreeItemIcon_SelectedExpanded) )
+ {
+ data->SetImage(image, wxTreeItemIcon_SelectedExpanded);
+ }
+}
+
+void wxTreeCtrl::DoSetItemImages(const wxTreeItemId& item,
+ int image,
+ int imageSel)
+{
+ wxTreeViewItem tvItem(item, TVIF_IMAGE | TVIF_SELECTEDIMAGE);
+ tvItem.iSelectedImage = imageSel;
+ tvItem.iImage = image;
+ DoSetItem(&tvItem);
+}
+
+int wxTreeCtrl::GetItemImage(const wxTreeItemId& item,
+ wxTreeItemIcon which) const
+{
+ if ( HasIndirectData(item) )
+ {
+ return DoGetItemImageFromData(item, which);
+ }
+
+ UINT mask;
+ switch ( which )
+ {
+ default:
+ wxFAIL_MSG( wxT("unknown tree item image type") );
+
+ case wxTreeItemIcon_Normal:
+ mask = TVIF_IMAGE;
+ break;
+
+ case wxTreeItemIcon_Selected:
+ mask = TVIF_SELECTEDIMAGE;
+ break;
+
+ case wxTreeItemIcon_Expanded:
+ case wxTreeItemIcon_SelectedExpanded:
+ return -1;
+ }
+
+ wxTreeViewItem tvItem(item, mask);
+ DoGetItem(&tvItem);
+
+ return mask == TVIF_IMAGE ? tvItem.iImage : tvItem.iSelectedImage;
+}
+
+void wxTreeCtrl::SetItemImage(const wxTreeItemId& item, int image,
+ wxTreeItemIcon which)
+{
+ int imageNormal, imageSel;
+ switch ( which )
+ {
+ default:
+ wxFAIL_MSG( wxT("unknown tree item image type") );
+
+ case wxTreeItemIcon_Normal:
+ imageNormal = image;
+ imageSel = GetItemSelectedImage(item);
+ break;
+
+ case wxTreeItemIcon_Selected:
+ imageNormal = GetItemImage(item);
+ imageSel = image;
+ break;
+
+ case wxTreeItemIcon_Expanded:
+ case wxTreeItemIcon_SelectedExpanded:
+ if ( !HasIndirectData(item) )
+ {
+ // we need to get the old images first, because after we create
+ // the wxTreeItemIndirectData GetItemXXXImage() will use it to
+ // get the images
+ imageNormal = GetItemImage(item);
+ imageSel = GetItemSelectedImage(item);
+
+ // if it doesn't have it yet, add it
+ wxTreeItemIndirectData *data = new
+ wxTreeItemIndirectData(this, item);
+
+ // copy the data to the new location
+ data->SetImage(imageNormal, wxTreeItemIcon_Normal);
+ data->SetImage(imageSel, wxTreeItemIcon_Selected);
+ }
+
+ DoSetItemImageFromData(item, image, which);
+
+ // reset the normal/selected images because we won't use them any
+ // more - now they're stored inside the indirect data
+ imageNormal =
+ imageSel = I_IMAGECALLBACK;
+ break;
+ }
+
+ // NB: at least in version 5.00.0518.9 of comctl32.dll we need to always
+ // change both normal and selected image - otherwise the change simply
+ // doesn't take place!
+ DoSetItemImages(item, imageNormal, imageSel);
+}
+
+wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const
+{
+ wxTreeViewItem tvItem(item, TVIF_PARAM);
+ if ( !DoGetItem(&tvItem) )
+ {
+ return NULL;
+ }
+
+ if ( HasIndirectData(item) )
+ {
+ return ((wxTreeItemIndirectData *)tvItem.lParam)->GetData();
+ }
+ else
+ {
+ return (wxTreeItemData *)tvItem.lParam;
+ }
+}
+
+void wxTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data)
+{
+ // first, associate this piece of data with this item
+ if ( data )
+ {
+ data->SetId(item);
+ }
+
+ wxTreeViewItem tvItem(item, TVIF_PARAM);
+
+ if ( HasIndirectData(item) )
+ {
+ if ( DoGetItem(&tvItem) )
+ {
+ ((wxTreeItemIndirectData *)tvItem.lParam)->SetData(data);
+ }
+ else
+ {
+ wxFAIL_MSG( wxT("failed to change tree items data") );
+ }
+ }
+ else
+ {
+ tvItem.lParam = (LPARAM)data;
+ DoSetItem(&tvItem);
+ }
+}
+
+void wxTreeCtrl::SetIndirectItemData(const wxTreeItemId& item,
+ wxTreeItemIndirectData *data)
+{
+ // this should never happen because it's unnecessary and will probably lead
+ // to crash too because the code elsewhere supposes that the pointer the
+ // wxTreeItemIndirectData has is a real wxItemData and not
+ // wxTreeItemIndirectData as well
+ wxASSERT_MSG( !HasIndirectData(item), wxT("setting indirect data twice?") );
+
+ SetItemData(item, (wxTreeItemData *)data);
+
+ m_itemsWithIndirectData.Add(item);
+}
+
+bool wxTreeCtrl::HasIndirectData(const wxTreeItemId& item) const
+{
+ return m_itemsWithIndirectData.Index(item) != wxNOT_FOUND;
+}
+
+void wxTreeCtrl::SetItemHasChildren(const wxTreeItemId& item, bool has)
+{
+ wxTreeViewItem tvItem(item, TVIF_CHILDREN);
+ tvItem.cChildren = (int)has;
+ DoSetItem(&tvItem);
+}
+
+void wxTreeCtrl::SetItemBold(const wxTreeItemId& item, bool bold)
+{
+ wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_BOLD);
+ tvItem.state = bold ? TVIS_BOLD : 0;
+ DoSetItem(&tvItem);
+}
+
+void wxTreeCtrl::SetItemDropHighlight(const wxTreeItemId& item, bool highlight)