// item can be deleted already in the model
int GetIndexOf( const wxDataViewItem &parent, const wxDataViewItem &item );
- virtual void OnInternalIdle();
+ void OnInternalIdle();
protected:
void InitTree();
}
}
+ // returns position of child node for given item in children list or wxNOT_FOUND
+ int FindChildByItem(const wxDataViewItem& item) const
+ {
+ const void* itemId = item.GetID();
+ const wxGtkTreeModelChildren& nodes = m_children;
+ const int len = nodes.size();
+ for ( int i = 0; i < len; i++ )
+ {
+ if ( nodes[i] == itemId )
+ return i;
+ }
+ return wxNOT_FOUND;
+ }
+
wxGtkTreeModelNode* GetParent()
{ return m_parent; }
wxGtkTreeModelNodes &GetNodes()
// Take care to not use GetOwner() here if the label is empty, we can be
// called from ctor when GetOwner() is still NULL in this case.
- g_value_set_string( &gvalue,
- m_label.empty() ? ""
- : wxGTK_CONV_FONT(m_label,
- GetOwner()->GetOwner()->GetFont())
- );
+ wxScopedCharBuffer buf;
+ if ( m_label.empty() )
+ buf = wxScopedCharBuffer::CreateNonOwned("");
+ else
+ buf = wxGTK_CONV_FONT(m_label, GetOwner()->GetOwner()->GetFont());
+
+ g_value_set_string( &gvalue, buf);
g_object_set_property( G_OBJECT(m_renderer), "text", &gvalue );
g_value_unset( &gvalue );
wxCHECK_MSG(parent_node, false,
"Did you forget a call to ItemAdded()? The parent node is unknown to the wxGtkTreeModel");
- wxDataViewItemArray siblings;
- m_wx_model->GetChildren(parent, siblings);
- int itemPos = siblings.Index(item, /*fromEnd=*/true);
- wxCHECK_MSG( itemPos != wxNOT_FOUND, false, "adding non-existent item?" );
+ wxDataViewItemArray modelSiblings;
+ m_wx_model->GetChildren(parent, modelSiblings);
+ const int modelSiblingsSize = modelSiblings.size();
+
+ int posInModel = modelSiblings.Index(item, /*fromEnd=*/true);
+ wxCHECK_MSG( posInModel != wxNOT_FOUND, false, "adding non-existent item?" );
+
+ const wxGtkTreeModelChildren& nodeSiblings = parent_node->GetChildren();
+ const int nodeSiblingsSize = nodeSiblings.size();
+
+ int nodePos = 0;
+
+ if ( posInModel == modelSiblingsSize - 1 )
+ {
+ nodePos = nodeSiblingsSize;
+ }
+ else if ( modelSiblingsSize == nodeSiblingsSize + 1 )
+ {
+ // This is the simple case when our node tree already matches the
+ // model and only this one item is missing.
+ nodePos = posInModel;
+ }
+ else
+ {
+ // It's possible that a larger discrepancy between the model and
+ // our realization exists. This can happen e.g. when adding a bunch
+ // of items to the model and then calling ItemsAdded() just once
+ // afterwards. In this case, we must find the right position by
+ // looking at sibling items.
+
+ // append to the end if we won't find a better position:
+ nodePos = nodeSiblingsSize;
+
+ for ( int nextItemPos = posInModel + 1;
+ nextItemPos < modelSiblingsSize;
+ nextItemPos++ )
+ {
+ int nextNodePos = parent_node->FindChildByItem(modelSiblings[nextItemPos]);
+ if ( nextNodePos != wxNOT_FOUND )
+ {
+ nodePos = nextNodePos;
+ break;
+ }
+ }
+ }
if (m_wx_model->IsContainer( item ))
- parent_node->InsertNode( new wxGtkTreeModelNode( parent_node, item, this ), itemPos );
+ parent_node->InsertNode( new wxGtkTreeModelNode( parent_node, item, this ), nodePos );
else
- parent_node->InsertLeaf( item.GetID(), itemPos );
+ parent_node->InsertLeaf( item.GetID(), nodePos );
}
ScheduleRefresh();
iter->stamp = m_gtk_model->stamp;
// user_data is just the index +1
- iter->user_data = (gpointer) (i+1);
+ iter->user_data = wxUIntToPtr(i+1);
return TRUE;
}
}
// user_data is just the index +1 (+2 because we need the next)
- iter->user_data = (gpointer) (n+2);
+ iter->user_data = wxUIntToPtr(n+2);
}
else
{
iter->stamp = m_gtk_model->stamp;
// user_data is just the index +1
- iter->user_data = (gpointer) (n+1);
+ iter->user_data = wxUIntToPtr(n+1);
return TRUE;
}