]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/dataview.cpp
Reordered "extern" and WXDLLIMPEXP_CORE specifiers; fixes #13816.
[wxWidgets.git] / src / gtk / dataview.cpp
index 0c03c24f5bf9d1a0be76a3a4239b34853e22527d..825bdd31d4e6bb35ed32ec36b46a4fe490fab282 100644 (file)
@@ -279,7 +279,7 @@ public:
     // item can be deleted already in the model
     int GetIndexOf( const wxDataViewItem &parent, const wxDataViewItem &item );
 
-    virtual void OnInternalIdle();
+    void OnInternalIdle();
 
 protected:
     void InitTree();
@@ -432,6 +432,20 @@ public:
             }
         }
 
+    // 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()
@@ -2556,11 +2570,13 @@ void wxDataViewProgressRenderer::GTKSetLabel()
 
     // 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 );
 
@@ -3672,15 +3688,56 @@ bool wxDataViewCtrlInternal::ItemAdded( const wxDataViewItem &parent, const wxDa
         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();
@@ -3757,7 +3814,7 @@ gboolean wxDataViewCtrlInternal::get_iter( GtkTreeIter *iter, GtkTreePath *path
 
         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;
     }
@@ -3860,7 +3917,7 @@ gboolean wxDataViewCtrlInternal::iter_next( GtkTreeIter *iter )
         }
 
         // 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
     {
@@ -4014,7 +4071,7 @@ gboolean wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter *iter, GtkTreeIter
 
         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;
     }