From 33ba5a05623023af942a6b34b0758a98b12d4c82 Mon Sep 17 00:00:00 2001
From: Robert Roebling <robert@roebling.de>
Date: Mon, 17 Dec 2007 13:56:28 +0000
Subject: [PATCH] Added wxDataViewListIndexModel::Reset(), clarified and
 corrected wxDataViewModel::Cleared(), corrected sample

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@50768 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/latex/wx/dataviewindexlistmodel.tex | 10 +++++
 docs/latex/wx/dataviewmodel.tex          |  3 +-
 include/wx/dataview.h                    |  1 +
 include/wx/gtk/dataview.h                |  2 +
 samples/dataview/dataview.cpp            | 39 +++++++++++--------
 src/common/datavcmn.cpp                  | 25 +++++++++++-
 src/generic/datavgen.cpp                 |  6 ++-
 src/gtk/dataview.cpp                     | 49 ++++++++++++++++++++----
 src/mac/carbon/dataview.cpp              |  7 +++-
 9 files changed, 114 insertions(+), 28 deletions(-)

diff --git a/docs/latex/wx/dataviewindexlistmodel.tex b/docs/latex/wx/dataviewindexlistmodel.tex
index 489ff84848..a83d691c57 100644
--- a/docs/latex/wx/dataviewindexlistmodel.tex
+++ b/docs/latex/wx/dataviewindexlistmodel.tex
@@ -73,6 +73,16 @@ Returns the position of given {\it item}.
 
 Override this to allow getting values from the model.
 
+
+\membersection{wxDataViewIndexListModel::Reset}\label{wxdataviewindexlistmodelreset}
+
+\func{void}{Reset}{\param{unsigned int }{new\_size}}
+
+Call this after if the data has to be read again from
+the model. This is useful after major changes when
+calling the methods below (possibly thousands of times)
+doesn't make sense.
+
 \membersection{wxDataViewIndexListModel::RowAppended}\label{wxdataviewindexlistmodelrowappended}
 
 \func{void}{RowAppended}{\void}
diff --git a/docs/latex/wx/dataviewmodel.tex b/docs/latex/wx/dataviewmodel.tex
index 7279f240e8..c14c20776c 100644
--- a/docs/latex/wx/dataviewmodel.tex
+++ b/docs/latex/wx/dataviewmodel.tex
@@ -124,7 +124,8 @@ to the model.
 
 \func{virtual bool}{Cleared}{\void}
 
-Called to inform the model that all data has been deleted.
+Called to inform the model that all data has been cleared. The
+control will reread the data from the model again.
 
 
 \membersection{wxDataViewModel::Compare}\label{wxdataviewmodelcompare}
diff --git a/include/wx/dataview.h b/include/wx/dataview.h
index 0f64e7f156..4cd43d4856 100644
--- a/include/wx/dataview.h
+++ b/include/wx/dataview.h
@@ -248,6 +248,7 @@ public:
     void RowsDeleted( const wxArrayInt &rows );
     void RowChanged( unsigned int row );
     void RowValueChanged( unsigned int row, unsigned int col );
+    void Reset( unsigned int new_size );
 
     // convert to/from row/wxDataViewItem
 
diff --git a/include/wx/gtk/dataview.h b/include/wx/gtk/dataview.h
index c85c6d34f7..1cb8787e83 100644
--- a/include/wx/gtk/dataview.h
+++ b/include/wx/gtk/dataview.h
@@ -417,6 +417,8 @@ private:
     friend class wxDataViewCtrlDCImpl;
     friend class wxDataViewColumn;
     friend class wxGtkDataViewModelNotifier;
+    friend class wxDataViewCtrlInternal;
+    
     GtkWidget               *m_treeview;
     wxDataViewModelNotifier *m_notifier;
     wxDataViewCtrlInternal  *m_internal;
diff --git a/samples/dataview/dataview.cpp b/samples/dataview/dataview.cpp
index bfa398f454..1c0685a04f 100644
--- a/samples/dataview/dataview.cpp
+++ b/samples/dataview/dataview.cpp
@@ -369,16 +369,22 @@ class MyListModel: public wxDataViewIndexListModel
 public:
     MyListModel() : 
 #ifdef __WXMAC__
-        wxDataViewIndexListModel( 1000 )
+        wxDataViewIndexListModel( 1000 + 100 )
 #else
-        wxDataViewIndexListModel( 100000 )
+        wxDataViewIndexListModel( 100000 + 100 )
 #endif
     {
+#ifdef __WXMAC__
+        m_virtualItems = 1000;
+#else
+        m_virtualItems = 100000;
+#endif
+
         unsigned int i;
         for (i = 0; i < 100; i++)
         {
             wxString str;
-            str.Printf( "row number %d", i );
+            str.Printf( "Test %d", i );
             m_array.Add( str );
         }
         
@@ -396,6 +402,9 @@ public:
     void DeleteItem( const wxDataViewItem &item )
     {
         unsigned int row = GetRow( item );
+        if (row >= m_array.GetCount())
+           return;
+           
         m_array.RemoveAt( row );
         RowDeleted( row );
     }
@@ -407,7 +416,8 @@ public:
         for (i = 0; i < items.GetCount(); i++)
         {
             unsigned int row = GetRow( items[i] );
-            rows.Add( row );
+            if (row < m_array.GetCount())
+                rows.Add( row );
         }
 
         // Sort in descending order so that the last
@@ -426,6 +436,8 @@ public:
     
     void AddMany()
     {
+        m_virtualItems += 1000;
+        Reset( m_array.GetCount() + m_virtualItems );
     }
 
     // implementation of base class virtuals to define model
@@ -443,11 +455,6 @@ public:
         return "string";
     }
     
-    virtual unsigned int GetRowCount()
-    {
-        return m_array.GetCount();
-    }
-    
     virtual void GetValue( wxVariant &variant, 
                            unsigned int row, unsigned int col ) const
     {
@@ -456,7 +463,7 @@ public:
             if (row >= m_array.GetCount())
             {
                 wxString str;
-                str.Printf( "row %d", row );
+                str.Printf( "row %d", row - m_array.GetCount() );
                 variant = str;
             }
             else
@@ -471,10 +478,10 @@ public:
         } else
         if (col==2)
         {
-            if ((row % 2) == 1)
-                variant = "Blue";
+            if (row >= m_array.GetCount())
+                variant = "plain";
             else
-                variant = "Italic";
+                variant = "blue italic";
         }
     }
     
@@ -483,10 +490,11 @@ public:
         if (col != 2)
             return false;
             
-        if ((row % 2) == 1)
+        if (row < m_array.GetCount())
+        {
             attr.SetColour( *wxBLUE );
-        else
             attr.SetItalic( true );
+        }
         
         return true;            
     }
@@ -508,6 +516,7 @@ public:
     
     wxArrayString    m_array;
     wxIcon           m_icon;
+    int              m_virtualItems;
 };
 
 // -------------------------------------
diff --git a/src/common/datavcmn.cpp b/src/common/datavcmn.cpp
index f487ba4d0c..a77fcb9387 100644
--- a/src/common/datavcmn.cpp
+++ b/src/common/datavcmn.cpp
@@ -326,6 +326,29 @@ wxDataViewIndexListModel::~wxDataViewIndexListModel()
 {
 }
 
+void wxDataViewIndexListModel::Reset( unsigned int new_size )
+{
+    if (m_useHash)
+    {
+        m_hash.Clear();
+    
+        // IDs are ordered until an item gets deleted or inserted
+        m_ordered = true;
+        
+        // build initial index
+        unsigned int i;
+        for (i = 1; i < new_size+1; i++)
+            m_hash.Add( (void*) i );
+        m_lastIndex = new_size + 1;
+    }
+    else
+    {
+        m_lastIndex = new_size-1;
+    }
+    
+    wxDataViewModel::Cleared();
+}
+
 void wxDataViewIndexListModel::RowPrepended()
 {
     if (m_useHash)
@@ -549,7 +572,7 @@ unsigned int wxDataViewIndexListModel::GetChildren( const wxDataViewItem &item,
         return 0;
 
     children = m_hash;
-
+    
     return m_hash.GetCount();
 }
 
diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp
index 5930e26a9f..a5d7e955fd 100644
--- a/src/generic/datavgen.cpp
+++ b/src/generic/datavgen.cpp
@@ -2206,9 +2206,11 @@ bool wxDataViewMainWindow::ValueChanged( const wxDataViewItem & item, unsigned i
 
 bool wxDataViewMainWindow::Cleared()
 {
-    SortPrepare();
-
     DestroyTree();
+    
+    SortPrepare();
+    BuildTree( GetOwner()->GetModel() );
+    
     UpdateDisplay();
 
     return true;
diff --git a/src/gtk/dataview.cpp b/src/gtk/dataview.cpp
index 978ddd716a..c8ea7178d3 100644
--- a/src/gtk/dataview.cpp
+++ b/src/gtk/dataview.cpp
@@ -525,9 +525,13 @@ wxgtk_tree_model_iter_next (GtkTreeModel  *tree_model,
                             GtkTreeIter   *iter)
 {
     GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model;
+    
+    if (wxtree_model->stamp != iter->stamp)
+       wxPrintf( "crash\n" );
+
     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE);
     g_return_val_if_fail (wxtree_model->stamp == iter->stamp, FALSE);
-
+    
     return wxtree_model->internal->iter_next( iter );
 }
 
@@ -1062,6 +1066,9 @@ public:
     virtual bool Cleared();
     virtual void Resort();
 
+    void SetGtkModel( GtkWxTreeModel *model ) { m_wxgtk_model = model; }
+
+private:
     GtkWxTreeModel      *m_wxgtk_model;
     wxDataViewModel     *m_wx_model;
     wxDataViewCtrl      *m_owner;
@@ -1184,10 +1191,15 @@ bool wxGtkDataViewModelNotifier::ValueChanged( const wxDataViewItem &item, unsig
 
 bool wxGtkDataViewModelNotifier::Cleared()
 {
-    // TODO: delete everything
-
+    gtk_tree_view_set_model( GTK_TREE_VIEW(m_owner->m_treeview), NULL );
+    
+    // this will create a new GTK model
     m_owner->GtkGetInternal()->Cleared();
+    
+    SetGtkModel( m_owner->GtkGetInternal()->GetGtkModel() );
 
+    gtk_tree_view_set_model( GTK_TREE_VIEW(m_owner->m_treeview), GTK_TREE_MODEL(m_wxgtk_model) );
+    
     return false;
 }
 
@@ -2610,6 +2622,22 @@ void wxDataViewCtrlInternal::BuildBranch( wxGtkTreeModelNode *node )
     }
 }
 
+bool wxDataViewCtrlInternal::Cleared()
+{
+    if (m_root)
+    {
+        delete m_root;
+        InitTree();
+    }   
+    
+    // Create new GTK model
+    g_object_unref( m_gtk_model );
+    m_gtk_model = wxgtk_tree_model_new();
+    m_gtk_model->internal = this;
+    
+    return true;
+}
+
 void wxDataViewCtrlInternal::Resort()
 {
     if (!m_wx_model->IsIndexListModel())
@@ -2665,11 +2693,6 @@ bool wxDataViewCtrlInternal::ValueChanged( const wxDataViewItem &item, unsigned
     return true;
 }
 
-bool wxDataViewCtrlInternal::Cleared()
-{
-    return true;
-}
-
 GtkTreeModelFlags wxDataViewCtrlInternal::get_flags()
 {
     if (m_wx_model->IsIndexListModel())
@@ -3332,6 +3355,7 @@ wxDataViewCtrl::~wxDataViewCtrl()
 void wxDataViewCtrl::Init()
 {
     m_notifier = NULL;
+    m_internal = NULL;
 }
 
 bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id,
@@ -3441,6 +3465,15 @@ void wxDataViewCtrl::OnInternalIdle()
 
 bool wxDataViewCtrl::AssociateModel( wxDataViewModel *model )
 {
+    if (GetModel())
+    {
+        delete m_internal;
+        m_internal = NULL;
+        
+        delete m_notifier;
+        m_notifier = NULL;
+    }
+    
     if (!wxDataViewCtrlBase::AssociateModel( model ))
         return false;
 
diff --git a/src/mac/carbon/dataview.cpp b/src/mac/carbon/dataview.cpp
index 2f993637e2..9b4a88fff9 100644
--- a/src/mac/carbon/dataview.cpp
+++ b/src/mac/carbon/dataview.cpp
@@ -367,7 +367,12 @@ public:
 
   virtual bool Cleared(void)
   {
-    return (this->m_dataViewControlPtr->RemoveItems() == noErr);
+    bool noFailureFlag = (this->m_dataViewControlPtr->RemoveItems() == noErr);
+    wxDataViewItem item;
+    wxDataViewItemArray array;
+    GetOwner()->GetChildren( item, array );
+    ItemsAdded( item, array );
+    return noFailureFlag;
   } /* Cleared(void) */
 
   virtual void Resort(void)
-- 
2.50.0

