Implement wxGTK internal short-cut for wxDataViewIndexListModel

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@50070 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
2007-11-18 23:54:57 +00:00
parent 1b12ec1259
commit 2056dede02
3 changed files with 348 additions and 142 deletions

View File

@@ -211,6 +211,9 @@ public:
unsigned int column, bool ascending );
virtual bool HasDefaultCompare() const { return false; }
// internal
virtual bool IsIndexListModel() const { return false; }
protected:
// the user should not delete this class directly: he should use DecRef() instead!
virtual ~wxDataViewModel() { }
@@ -266,10 +269,15 @@ public:
virtual bool IsContainer( const wxDataViewItem &item ) const;
virtual unsigned int GetChildren( const wxDataViewItem &item, wxDataViewItemArray &children ) const;
// internal
virtual bool IsIndexListModel() const { return true; }
unsigned int GetLastIndex() const { return m_lastIndex; }
private:
wxDataViewItemArray m_hash;
unsigned int m_lastIndex;
bool m_ordered;
bool m_useHash;
};

View File

@@ -299,6 +299,15 @@ int wxDataViewModel::Compare( const wxDataViewItem &item1, const wxDataViewItem
wxDataViewIndexListModel::wxDataViewIndexListModel( unsigned int initial_size )
{
#ifdef __WXGTK__
m_useHash = false;
#else
m_useHash = true;
#endif
if (m_useHash)
{
// IDs are ordered until an item gets deleted or inserted
m_ordered = true;
// build initial index
@@ -306,6 +315,11 @@ wxDataViewIndexListModel::wxDataViewIndexListModel( unsigned int initial_size )
for (i = 1; i < initial_size+1; i++)
m_hash.Add( (void*) i );
m_lastIndex = initial_size + 1;
}
else
{
m_lastIndex = initial_size-1;
}
}
wxDataViewIndexListModel::~wxDataViewIndexListModel()
@@ -314,37 +328,73 @@ wxDataViewIndexListModel::~wxDataViewIndexListModel()
void wxDataViewIndexListModel::RowPrepended()
{
if (m_useHash)
{
m_ordered = false;
unsigned int id = m_lastIndex++;
m_hash.Insert( (void*) id, 0 );
wxDataViewItem item( (void*) id );
ItemAdded( wxDataViewItem(0), item );
}
else
{
m_lastIndex++;
wxDataViewItem item( (void*) 0 );
ItemAdded( wxDataViewItem(0), item );
}
}
void wxDataViewIndexListModel::RowInserted( unsigned int before )
{
if (m_useHash)
{
m_ordered = false;
unsigned int id = m_lastIndex++;
m_hash.Insert( (void*) id, before );
wxDataViewItem item( (void*) id );
ItemAdded( wxDataViewItem(0), item );
}
else
{
m_lastIndex++;
wxDataViewItem item( (void*) before );
ItemAdded( wxDataViewItem(0), item );
}
}
void wxDataViewIndexListModel::RowAppended()
{
if (m_useHash)
{
unsigned int id = m_lastIndex++;
m_hash.Add( (void*) id );
wxDataViewItem item( (void*) id );
ItemAdded( wxDataViewItem(0), item );
}
else
{
m_lastIndex++;
wxDataViewItem item( (void*) m_lastIndex );
ItemAdded( wxDataViewItem(0), item );
}
}
void wxDataViewIndexListModel::RowDeleted( unsigned int row )
{
if (m_useHash)
{
wxDataViewItem item( m_hash[row] );
wxDataViewModel::ItemDeleted( wxDataViewItem(0), item );
m_hash.RemoveAt( row );
}
else
{
wxDataViewItem item( (void*) row );
wxDataViewModel::ItemDeleted( wxDataViewItem(0), item );
m_lastIndex++;
}
}
void wxDataViewIndexListModel::RowChanged( unsigned int row )
@@ -359,20 +409,34 @@ void wxDataViewIndexListModel::RowValueChanged( unsigned int row, unsigned int c
unsigned int wxDataViewIndexListModel::GetRow( const wxDataViewItem &item ) const
{
if (m_useHash)
{
if (m_ordered)
{
unsigned int pos = wxPtrToUInt(item.GetID());
unsigned int pos = wxPtrToUInt( item.GetID() );
return pos-1;
}
// assert for not found
return (unsigned int) m_hash.Index( item.GetID() );
}
else
{
return wxPtrToUInt( item.GetID() );
}
}
wxDataViewItem wxDataViewIndexListModel::GetItem( unsigned int row ) const
{
if (m_useHash)
{
wxASSERT( row < m_hash.GetCount() );
return wxDataViewItem( m_hash[row] );
}
else
{
return wxDataViewItem( (void*) row );
}
}
bool wxDataViewIndexListModel::HasDefaultCompare() const
@@ -385,7 +449,7 @@ int wxDataViewIndexListModel::Compare(const wxDataViewItem& item1,
unsigned int WXUNUSED(column),
bool ascending)
{
if (m_ordered)
if (m_ordered || !m_useHash)
{
unsigned int pos1 = wxPtrToUInt(item1.GetID());
unsigned int pos2 = wxPtrToUInt(item2.GetID());
@@ -435,6 +499,9 @@ bool wxDataViewIndexListModel::IsContainer( const wxDataViewItem &item ) const
unsigned int wxDataViewIndexListModel::GetChildren( const wxDataViewItem &item, wxDataViewItemArray &children ) const
{
if (m_useHash)
return 0; // error
if (item.IsOk())
return 0;

View File

@@ -59,6 +59,7 @@ public:
wxDataViewCtrlInternal( wxDataViewCtrl *owner, wxDataViewModel *wx_model, GtkWxTreeModel *owner );
~wxDataViewCtrlInternal();
GtkTreeModelFlags get_flags();
gboolean get_iter( GtkTreeIter *iter, GtkTreePath *path );
GtkTreePath *get_path( GtkTreeIter *iter);
gboolean iter_next( GtkTreeIter *iter );
@@ -431,9 +432,10 @@ wxgtk_tree_model_finalize (GObject *object)
static GtkTreeModelFlags
wxgtk_tree_model_get_flags (GtkTreeModel *tree_model)
{
g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (tree_model), (GtkTreeModelFlags)0 );
GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model;
g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), (GtkTreeModelFlags)0 );
return GTK_TREE_MODEL_ITERS_PERSIST;
return wxtree_model->internal->get_flags();
}
static gint
@@ -938,7 +940,7 @@ gtk_wx_cell_renderer_render (GtkCellRenderer *renderer,
wxRect renderrect( rect.x, rect.y, rect.width, rect.height );
wxWindowDC* dc = (wxWindowDC*) cell->GetDC();
#if wxUSE_NEW_DC
wxGTKWindowImplDC *impldc = (wxGTKWindowImplDC *) dc->GetImpl();
wxGTKWindowDCImpl *impldc = (wxGTKWindowDCImpl *) dc->GetImpl();
if (impldc->m_window == NULL)
{
impldc->m_window = window;
@@ -1661,7 +1663,7 @@ public:
wxDataViewCtrlDC( wxDataViewCtrl *window )
{
#if wxUSE_NEW_DC
wxGTKWindowImplDC *impl = (wxGTKWindowImplDC*) GetImpl();
wxGTKWindowDCImpl *impl = (wxGTKWindowDCImpl*) GetImpl();
GtkWidget *widget = window->m_treeview;
// Set later
@@ -2107,6 +2109,9 @@ static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *column,
wxDataViewModel *wx_model = tree_model->internal->GetDataViewModel();
if (!wx_model->IsIndexListModel())
{
if (wx_model->IsContainer( item ))
{
if (wx_model->HasContainerColumns( item ) || (cell->GetOwner()->GetModelColumn() == 0))
@@ -2137,6 +2142,8 @@ static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *column,
g_value_unset( &gvalue );
}
}
wxVariant value;
wx_model->GetValue( value, item, cell->GetOwner()->GetModelColumn() );
@@ -2571,6 +2578,8 @@ wxDataViewCtrlInternal::wxDataViewCtrlInternal( wxDataViewCtrl *owner,
m_sort_order = GTK_SORT_ASCENDING;
m_sort_column = -1;
m_dataview_sort_column = NULL;
if (!m_wx_model->IsIndexListModel())
InitTree();
}
@@ -2610,24 +2619,31 @@ void wxDataViewCtrlInternal::BuildBranch( wxGtkTreeModelNode *node )
void wxDataViewCtrlInternal::Resort()
{
if (!m_wx_model->IsIndexListModel())
m_root->Resort();
}
bool wxDataViewCtrlInternal::ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item )
{
if (!m_wx_model->IsIndexListModel())
{
wxGtkTreeModelNode *parent_node = FindNode( parent );
if (m_wx_model->IsContainer( item ))
parent_node->AddNode( new wxGtkTreeModelNode( parent_node, item, this ) );
else
parent_node->AddLeave( item.GetID() );
}
return true;
}
bool wxDataViewCtrlInternal::ItemDeleted( const wxDataViewItem &parent, const wxDataViewItem &item )
{
if (!m_wx_model->IsIndexListModel())
{
wxGtkTreeModelNode *parent_node = FindNode( parent );
parent_node->DeleteChild( item.GetID() );
}
return true;
}
@@ -2661,8 +2677,33 @@ bool wxDataViewCtrlInternal::Cleared()
return true;
}
GtkTreeModelFlags wxDataViewCtrlInternal::get_flags()
{
if (m_wx_model->IsIndexListModel())
return GTK_TREE_MODEL_LIST_ONLY;
else
return GTK_TREE_MODEL_ITERS_PERSIST;
}
gboolean wxDataViewCtrlInternal::get_iter( GtkTreeIter *iter, GtkTreePath *path )
{
if (m_wx_model->IsIndexListModel())
{
wxDataViewIndexListModel *wx_model = (wxDataViewIndexListModel*) m_wx_model;
unsigned int i = (unsigned int)gtk_tree_path_get_indices (path)[0];
if (i >= wx_model->GetLastIndex())
return FALSE;
iter->stamp = m_gtk_model->stamp;
// user_data is just the index
iter->user_data = (gpointer) i;
return TRUE;
}
else
{
int depth = gtk_tree_path_get_depth( path );
wxGtkTreeModelNode *node = m_root;
@@ -2697,6 +2738,7 @@ gboolean wxDataViewCtrlInternal::get_iter( GtkTreeIter *iter, GtkTreePath *path
}
}
}
}
return FALSE;
}
@@ -2704,6 +2746,15 @@ gboolean wxDataViewCtrlInternal::get_iter( GtkTreeIter *iter, GtkTreePath *path
GtkTreePath *wxDataViewCtrlInternal::get_path( GtkTreeIter *iter )
{
GtkTreePath *retval = gtk_tree_path_new ();
if (m_wx_model->IsIndexListModel())
{
// user_data is just the index
int i = (wxUIntPtr) iter->user_data;
gtk_tree_path_append_index (retval, i);
}
else
{
void *id = iter->user_data;
wxGtkTreeModelNode *node = FindParentNode( iter );
@@ -2716,12 +2767,29 @@ GtkTreePath *wxDataViewCtrlInternal::get_path( GtkTreeIter *iter )
id = node->GetItem().GetID();
node = node->GetParent();
}
}
return retval;
}
gboolean wxDataViewCtrlInternal::iter_next( GtkTreeIter *iter )
{
if (m_wx_model->IsIndexListModel())
{
wxDataViewIndexListModel *wx_model = (wxDataViewIndexListModel*) m_wx_model;
int n = (wxUIntPtr) iter->user_data;
if (n == -1)
return FALSE;
if (n >= (int) wx_model->GetLastIndex()-2)
return FALSE;
iter->user_data = (gpointer) ++n;
}
else
{
wxGtkTreeModelNode *parent = FindParentNode( iter );
if( parent == NULL )
return FALSE;
@@ -2733,12 +2801,26 @@ gboolean wxDataViewCtrlInternal::iter_next( GtkTreeIter *iter )
iter->stamp = m_gtk_model->stamp;
iter->user_data = parent->GetChildren().Item( pos+1 );
}
return TRUE;
}
gboolean wxDataViewCtrlInternal::iter_children( GtkTreeIter *iter, GtkTreeIter *parent )
{
if (m_wx_model->IsIndexListModel())
{
// this is a list, nodes have no children
if (parent)
return FALSE;
iter->stamp = m_gtk_model->stamp;
iter->user_data = (gpointer) -1;
return TRUE;
}
else
{
wxDataViewItem item( (void*) parent->user_data );
if (!m_wx_model->IsContainer( item ))
@@ -2752,12 +2834,20 @@ gboolean wxDataViewCtrlInternal::iter_children( GtkTreeIter *iter, GtkTreeIter *
iter->stamp = m_gtk_model->stamp;
iter->user_data = (gpointer) parent_node->GetChildren().Item( 0 );
}
return TRUE;
}
gboolean wxDataViewCtrlInternal::iter_has_child( GtkTreeIter *iter )
{
if (m_wx_model->IsIndexListModel())
{
// this is a list, nodes have no children
return FALSE;
}
else
{
wxDataViewItem item( (void*) iter->user_data );
bool is_container = m_wx_model->IsContainer( item );
@@ -2769,10 +2859,22 @@ gboolean wxDataViewCtrlInternal::iter_has_child( GtkTreeIter *iter )
BuildBranch( node );
return (node->GetChildCount() > 0);
}
}
gint wxDataViewCtrlInternal::iter_n_children( GtkTreeIter *iter )
{
if (m_wx_model->IsIndexListModel())
{
wxDataViewIndexListModel *wx_model = (wxDataViewIndexListModel*) m_wx_model;
if (iter == NULL)
return (gint) wx_model->GetLastIndex()-1;
return 0;
}
else
{
wxDataViewItem item( (void*) iter->user_data );
if (!m_wx_model->IsContainer( item ))
@@ -2784,10 +2886,31 @@ gint wxDataViewCtrlInternal::iter_n_children( GtkTreeIter *iter )
// wxPrintf( "iter_n_children %d\n", parent_node->GetChildCount() );
return parent_node->GetChildCount();
}
}
gboolean wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter *iter, GtkTreeIter *parent, gint n )
{
if (m_wx_model->IsIndexListModel())
{
wxDataViewIndexListModel *wx_model = (wxDataViewIndexListModel*) m_wx_model;
if (parent)
return FALSE;
if (n < 0)
return FALSE;
if (n >= (gint) wx_model->GetLastIndex()-1)
return FALSE;
iter->stamp = m_gtk_model->stamp;
iter->user_data = (gpointer) n;
return TRUE;
}
else
{
void* id = NULL;
if (parent) id = (void*) parent->user_data;
wxDataViewItem item( id );
@@ -2804,10 +2927,17 @@ gboolean wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter *iter, GtkTreeIter
iter->user_data = parent_node->GetChildren().Item( n );
return TRUE;
}
}
gboolean wxDataViewCtrlInternal::iter_parent( GtkTreeIter *iter, GtkTreeIter *child )
{
if (m_wx_model->IsIndexListModel())
{
return FALSE;
}
else
{
wxGtkTreeModelNode *node = FindParentNode( child );
if (!node)
return FALSE;
@@ -2816,6 +2946,7 @@ gboolean wxDataViewCtrlInternal::iter_parent( GtkTreeIter *iter, GtkTreeIter *ch
iter->user_data = (gpointer) node->GetItem().GetID();
return TRUE;
}
}
static wxGtkTreeModelNode*