Moved more code from wxDataViewCtrl to wxDataViewCtrlInternal.
Add new special API for wxDataViewVirtualIndexModel::Reset() as wxDataViewModel::Clear is something different and needs a different, two step API under GTK+, one for destroying the current view and one for rereading the new contents. Added ::BeforeReset() and ::AfterReset() notifications for that purpose. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65533 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
5249673498
commit
673810eeb8
@ -125,6 +125,10 @@ public:
|
||||
virtual bool ItemsChanged( const wxDataViewItemArray &items );
|
||||
virtual bool ValueChanged( const wxDataViewItem &item, unsigned int col ) = 0;
|
||||
virtual bool Cleared() = 0;
|
||||
|
||||
// this is needed for the virtual list model under GTK+
|
||||
virtual bool BeforeReset( size_t WXUNUSED(old_size), size_t WXUNUSED(new_size) ) { return true; }
|
||||
virtual bool AfterReset() { return Cleared(); }
|
||||
|
||||
virtual void Resort() = 0;
|
||||
|
||||
@ -245,7 +249,12 @@ public:
|
||||
bool ValueChanged( const wxDataViewItem &item, unsigned int col );
|
||||
bool Cleared();
|
||||
|
||||
// delegatd action
|
||||
// this is needed for the virtual list model under GTK+
|
||||
bool BeforeReset( size_t old_size, size_t new_size );
|
||||
bool AfterReset();
|
||||
|
||||
|
||||
// delegated action
|
||||
virtual void Resort();
|
||||
|
||||
void AddNotifier( wxDataViewModelNotifier *notifier );
|
||||
|
@ -195,11 +195,9 @@ private:
|
||||
|
||||
friend class wxDataViewCtrlDCImpl;
|
||||
friend class wxDataViewColumn;
|
||||
friend class wxGtkDataViewModelNotifier;
|
||||
friend class wxDataViewCtrlInternal;
|
||||
|
||||
GtkWidget *m_treeview;
|
||||
wxDataViewModelNotifier *m_notifier;
|
||||
wxDataViewCtrlInternal *m_internal;
|
||||
wxDataViewColumnList m_cols;
|
||||
|
||||
|
@ -235,6 +235,36 @@ bool wxDataViewModel::Cleared()
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool wxDataViewModel::BeforeReset( size_t old_size, size_t new_size )
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
wxDataViewModelNotifiers::iterator iter;
|
||||
for (iter = m_notifiers.begin(); iter != m_notifiers.end(); ++iter)
|
||||
{
|
||||
wxDataViewModelNotifier* notifier = *iter;
|
||||
if (!notifier->BeforeReset(old_size,new_size))
|
||||
ret = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool wxDataViewModel::AfterReset()
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
wxDataViewModelNotifiers::iterator iter;
|
||||
for (iter = m_notifiers.begin(); iter != m_notifiers.end(); ++iter)
|
||||
{
|
||||
wxDataViewModelNotifier* notifier = *iter;
|
||||
if (!notifier->AfterReset())
|
||||
ret = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void wxDataViewModel::Resort()
|
||||
{
|
||||
wxDataViewModelNotifiers::iterator iter;
|
||||
@ -499,9 +529,11 @@ wxDataViewVirtualListModel::wxDataViewVirtualListModel( unsigned int initial_siz
|
||||
|
||||
void wxDataViewVirtualListModel::Reset( unsigned int new_size )
|
||||
{
|
||||
m_size = new_size;
|
||||
/* wxDataViewModel:: */ BeforeReset( m_size, new_size );
|
||||
|
||||
/* wxDataViewModel:: */ Cleared();
|
||||
m_size = new_size;
|
||||
|
||||
/* wxDataViewModel:: */ AfterReset();
|
||||
}
|
||||
|
||||
void wxDataViewVirtualListModel::RowPrepended()
|
||||
|
@ -36,6 +36,8 @@
|
||||
#include "wx/gtk/private/gdkconv.h"
|
||||
using namespace wxGTKImpl;
|
||||
|
||||
class wxGtkDataViewModelNotifier;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -197,7 +199,7 @@ WX_DEFINE_LIST(ItemList)
|
||||
class wxDataViewCtrlInternal
|
||||
{
|
||||
public:
|
||||
wxDataViewCtrlInternal( wxDataViewCtrl *owner, wxDataViewModel *wx_model, GtkWxTreeModel *gtk_model );
|
||||
wxDataViewCtrlInternal( wxDataViewCtrl *owner, wxDataViewModel *wx_model );
|
||||
~wxDataViewCtrlInternal();
|
||||
|
||||
// model iface
|
||||
@ -231,6 +233,8 @@ public:
|
||||
bool ItemChanged( const wxDataViewItem &item );
|
||||
bool ValueChanged( const wxDataViewItem &item, unsigned int col );
|
||||
bool Cleared();
|
||||
bool BeforeReset(size_t old_Size,size_t new_size);
|
||||
bool AfterReset();
|
||||
void Resort();
|
||||
|
||||
// sorting interface
|
||||
@ -278,6 +282,8 @@ private:
|
||||
GtkTargetEntry m_dropTargetTargetEntry;
|
||||
wxCharBuffer m_dropTargetTargetEntryTarget;
|
||||
wxDataObject *m_dropDataObject;
|
||||
|
||||
wxGtkDataViewModelNotifier *m_notifier;
|
||||
};
|
||||
|
||||
|
||||
@ -1472,9 +1478,7 @@ gtk_wx_cell_renderer_activate(
|
||||
class wxGtkDataViewModelNotifier: public wxDataViewModelNotifier
|
||||
{
|
||||
public:
|
||||
wxGtkDataViewModelNotifier( GtkWxTreeModel *wxgtk_model,
|
||||
wxDataViewModel *wx_model,
|
||||
wxDataViewCtrl *ctrl );
|
||||
wxGtkDataViewModelNotifier( wxDataViewModel *wx_model, wxDataViewCtrlInternal *internal );
|
||||
~wxGtkDataViewModelNotifier();
|
||||
|
||||
virtual bool ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item );
|
||||
@ -1483,13 +1487,14 @@ public:
|
||||
virtual bool ValueChanged( const wxDataViewItem &item, unsigned int col );
|
||||
virtual bool Cleared();
|
||||
virtual void Resort();
|
||||
|
||||
void SetGtkModel( GtkWxTreeModel *model ) { m_wxgtk_model = model; }
|
||||
virtual bool BeforeReset(size_t old_size,size_t new_size);
|
||||
virtual bool AfterReset();
|
||||
|
||||
void UpdateLastCount();
|
||||
|
||||
private:
|
||||
GtkWxTreeModel *m_wxgtk_model;
|
||||
wxDataViewModel *m_wx_model;
|
||||
wxDataViewCtrl *m_owner;
|
||||
wxDataViewModel *m_wx_model;
|
||||
wxDataViewCtrlInternal *m_internal;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------
|
||||
@ -1497,105 +1502,110 @@ private:
|
||||
// ---------------------------------------------------------
|
||||
|
||||
wxGtkDataViewModelNotifier::wxGtkDataViewModelNotifier(
|
||||
GtkWxTreeModel* wxgtk_model, wxDataViewModel *wx_model,
|
||||
wxDataViewCtrl *ctrl )
|
||||
wxDataViewModel *wx_model, wxDataViewCtrlInternal *internal )
|
||||
{
|
||||
m_wxgtk_model = wxgtk_model;
|
||||
m_wx_model = wx_model;
|
||||
m_owner = ctrl;
|
||||
m_internal = internal;
|
||||
}
|
||||
|
||||
wxGtkDataViewModelNotifier::~wxGtkDataViewModelNotifier()
|
||||
{
|
||||
m_wx_model = NULL;
|
||||
m_wxgtk_model = NULL;
|
||||
m_internal = NULL;
|
||||
}
|
||||
|
||||
bool wxGtkDataViewModelNotifier::ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item )
|
||||
{
|
||||
m_owner->GtkGetInternal()->ItemAdded( parent, item );
|
||||
m_internal->ItemAdded( parent, item );
|
||||
GtkWxTreeModel *wxgtk_model = m_internal->GetGtkModel();
|
||||
|
||||
GtkTreeIter iter;
|
||||
iter.stamp = m_wxgtk_model->stamp;
|
||||
iter.stamp = wxgtk_model->stamp;
|
||||
iter.user_data = item.GetID();
|
||||
|
||||
wxGtkTreePath path(wxgtk_tree_model_get_path(
|
||||
GTK_TREE_MODEL(m_wxgtk_model), &iter ));
|
||||
GTK_TREE_MODEL(wxgtk_model), &iter ));
|
||||
gtk_tree_model_row_inserted(
|
||||
GTK_TREE_MODEL(m_wxgtk_model), path, &iter);
|
||||
GTK_TREE_MODEL(wxgtk_model), path, &iter);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxGtkDataViewModelNotifier::ItemDeleted( const wxDataViewItem &parent, const wxDataViewItem &item )
|
||||
{
|
||||
GtkWxTreeModel *wxgtk_model = m_internal->GetGtkModel();
|
||||
#if 0
|
||||
// using _get_path for a deleted item cannot be
|
||||
// a good idea
|
||||
GtkTreeIter iter;
|
||||
iter.stamp = m_wxgtk_model->stamp;
|
||||
iter.stamp = wxgtk_model->stamp;
|
||||
iter.user_data = (gpointer) item.GetID();
|
||||
wxGtkTreePath path(wxgtk_tree_model_get_path(
|
||||
GTK_TREE_MODEL(m_wxgtk_model), &iter ));
|
||||
GTK_TREE_MODEL(wxgtk_model), &iter ));
|
||||
#else
|
||||
// so get the path from the parent
|
||||
GtkTreeIter iter;
|
||||
iter.stamp = m_wxgtk_model->stamp;
|
||||
iter.stamp = wxgtk_model->stamp;
|
||||
iter.user_data = (gpointer) parent.GetID();
|
||||
wxGtkTreePath path(wxgtk_tree_model_get_path(
|
||||
GTK_TREE_MODEL(m_wxgtk_model), &iter ));
|
||||
GTK_TREE_MODEL(wxgtk_model), &iter ));
|
||||
// and add the final index ourselves
|
||||
int index = m_owner->GtkGetInternal()->GetIndexOf( parent, item );
|
||||
int index = m_internal->GetIndexOf( parent, item );
|
||||
gtk_tree_path_append_index( path, index );
|
||||
#endif
|
||||
|
||||
gtk_tree_model_row_deleted(
|
||||
GTK_TREE_MODEL(m_wxgtk_model), path );
|
||||
GTK_TREE_MODEL(wxgtk_model), path );
|
||||
|
||||
m_owner->GtkGetInternal()->ItemDeleted( parent, item );
|
||||
m_internal->ItemDeleted( parent, item );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void wxGtkDataViewModelNotifier::Resort()
|
||||
{
|
||||
m_owner->GtkGetInternal()->Resort();
|
||||
m_internal->Resort();
|
||||
}
|
||||
|
||||
bool wxGtkDataViewModelNotifier::ItemChanged( const wxDataViewItem &item )
|
||||
{
|
||||
GtkWxTreeModel *wxgtk_model = m_internal->GetGtkModel();
|
||||
|
||||
GtkTreeIter iter;
|
||||
iter.stamp = m_wxgtk_model->stamp;
|
||||
iter.stamp = wxgtk_model->stamp;
|
||||
iter.user_data = (gpointer) item.GetID();
|
||||
|
||||
wxGtkTreePath path(wxgtk_tree_model_get_path(
|
||||
GTK_TREE_MODEL(m_wxgtk_model), &iter ));
|
||||
GTK_TREE_MODEL(wxgtk_model), &iter ));
|
||||
gtk_tree_model_row_changed(
|
||||
GTK_TREE_MODEL(m_wxgtk_model), path, &iter );
|
||||
GTK_TREE_MODEL(wxgtk_model), path, &iter );
|
||||
|
||||
m_owner->GtkGetInternal()->ItemChanged( item );
|
||||
m_internal->ItemChanged( item );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxGtkDataViewModelNotifier::ValueChanged( const wxDataViewItem &item, unsigned int model_col )
|
||||
{
|
||||
GtkWxTreeModel *wxgtk_model = m_internal->GetGtkModel();
|
||||
wxDataViewCtrl *ctrl = m_internal->GetOwner();
|
||||
|
||||
// This adds GTK+'s missing MVC logic for ValueChanged
|
||||
unsigned int index;
|
||||
for (index = 0; index < m_owner->GetColumnCount(); index++)
|
||||
for (index = 0; index < ctrl->GetColumnCount(); index++)
|
||||
{
|
||||
wxDataViewColumn *column = m_owner->GetColumn( index );
|
||||
wxDataViewColumn *column = ctrl->GetColumn( index );
|
||||
if (column->GetModelColumn() == model_col)
|
||||
{
|
||||
GtkTreeView *widget = GTK_TREE_VIEW(m_owner->m_treeview);
|
||||
GtkTreeView *widget = GTK_TREE_VIEW(ctrl->GtkGetTreeView());
|
||||
GtkTreeViewColumn *gcolumn = GTK_TREE_VIEW_COLUMN(column->GetGtkHandle());
|
||||
|
||||
// Get cell area
|
||||
GtkTreeIter iter;
|
||||
iter.stamp = m_wxgtk_model->stamp;
|
||||
iter.stamp = wxgtk_model->stamp;
|
||||
iter.user_data = (gpointer) item.GetID();
|
||||
wxGtkTreePath path(wxgtk_tree_model_get_path(
|
||||
GTK_TREE_MODEL(m_wxgtk_model), &iter ));
|
||||
GTK_TREE_MODEL(wxgtk_model), &iter ));
|
||||
GdkRectangle cell_area;
|
||||
gtk_tree_view_get_cell_area( widget, path, gcolumn, &cell_area );
|
||||
|
||||
@ -1608,7 +1618,7 @@ bool wxGtkDataViewModelNotifier::ValueChanged( const wxDataViewItem &item, unsig
|
||||
gtk_widget_queue_draw_area( GTK_WIDGET(widget),
|
||||
cell_area.x - xdiff, ydiff + cell_area.y, cell_area.width, cell_area.height );
|
||||
|
||||
m_owner->GtkGetInternal()->ValueChanged( item, model_col );
|
||||
m_internal->ValueChanged( item, model_col );
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1617,23 +1627,45 @@ bool wxGtkDataViewModelNotifier::ValueChanged( const wxDataViewItem &item, unsig
|
||||
return false;
|
||||
}
|
||||
|
||||
bool wxGtkDataViewModelNotifier::BeforeReset(size_t WXUNUSED(old_size), size_t WXUNUSED(new_size))
|
||||
{
|
||||
GtkWidget *treeview = m_internal->GetOwner()->GtkGetTreeView();
|
||||
gtk_tree_view_set_model( GTK_TREE_VIEW(treeview), NULL );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxGtkDataViewModelNotifier::AfterReset()
|
||||
{
|
||||
GtkWxTreeModel *wxgtk_model = m_internal->GetGtkModel();
|
||||
GtkWidget *treeview = m_internal->GetOwner()->GtkGetTreeView();
|
||||
|
||||
gtk_tree_view_set_model( GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(wxgtk_model) );
|
||||
|
||||
m_internal->Cleared();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxGtkDataViewModelNotifier::Cleared()
|
||||
{
|
||||
GtkWxTreeModel *wxgtk_model = m_internal->GetGtkModel();
|
||||
|
||||
// There is no call to tell the model that everything
|
||||
// has been deleted so call row_deleted() for every
|
||||
// child of root...
|
||||
|
||||
int count = m_owner->GtkGetInternal()->iter_n_children( NULL ); // number of children of root
|
||||
|
||||
int count = m_internal->iter_n_children( NULL ); // number of children of root
|
||||
|
||||
GtkTreePath *path = gtk_tree_path_new_first(); // points to root
|
||||
|
||||
int i;
|
||||
for (i = 0; i < count; i++)
|
||||
gtk_tree_model_row_deleted( GTK_TREE_MODEL(m_wxgtk_model), path );
|
||||
gtk_tree_model_row_deleted( GTK_TREE_MODEL(wxgtk_model), path );
|
||||
|
||||
gtk_tree_path_free( path );
|
||||
|
||||
m_owner->GtkGetInternal()->Cleared();
|
||||
m_internal->Cleared();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -3344,12 +3376,12 @@ void wxGtkTreeModelNode::Resort()
|
||||
// wxDataViewCtrlInternal
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
wxDataViewCtrlInternal::wxDataViewCtrlInternal( wxDataViewCtrl *owner,
|
||||
wxDataViewModel *wx_model, GtkWxTreeModel *gtk_model )
|
||||
wxDataViewCtrlInternal::wxDataViewCtrlInternal( wxDataViewCtrl *owner, wxDataViewModel *wx_model )
|
||||
{
|
||||
m_owner = owner;
|
||||
m_wx_model = wx_model;
|
||||
m_gtk_model = gtk_model;
|
||||
|
||||
m_gtk_model = NULL;
|
||||
m_root = NULL;
|
||||
m_sort_order = GTK_SORT_ASCENDING;
|
||||
m_sort_column = -1;
|
||||
@ -3358,12 +3390,28 @@ wxDataViewCtrlInternal::wxDataViewCtrlInternal( wxDataViewCtrl *owner,
|
||||
m_dragDataObject = NULL;
|
||||
m_dropDataObject = NULL;
|
||||
|
||||
m_gtk_model = wxgtk_tree_model_new();
|
||||
m_gtk_model->internal = this;
|
||||
|
||||
m_notifier = new wxGtkDataViewModelNotifier( wx_model, this );
|
||||
|
||||
wx_model->AddNotifier( m_notifier );
|
||||
|
||||
// g_object_unref( gtk_model ); ???
|
||||
|
||||
if (!m_wx_model->IsVirtualListModel())
|
||||
InitTree();
|
||||
|
||||
gtk_tree_view_set_model( GTK_TREE_VIEW(m_owner->GtkGetTreeView()), GTK_TREE_MODEL(m_gtk_model) );
|
||||
}
|
||||
|
||||
wxDataViewCtrlInternal::~wxDataViewCtrlInternal()
|
||||
{
|
||||
m_wx_model->RemoveNotifier( m_notifier );
|
||||
|
||||
// remove the model from the GtkTreeView before it gets destroyed
|
||||
gtk_tree_view_set_model( GTK_TREE_VIEW( m_owner->GtkGetTreeView() ), NULL );
|
||||
|
||||
g_object_unref( m_gtk_model );
|
||||
|
||||
delete m_dragDataObject;
|
||||
@ -4340,21 +4388,13 @@ IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl, wxDataViewCtrlBase)
|
||||
|
||||
wxDataViewCtrl::~wxDataViewCtrl()
|
||||
{
|
||||
if (m_notifier)
|
||||
GetModel()->RemoveNotifier( m_notifier );
|
||||
|
||||
m_cols.Clear();
|
||||
|
||||
// remove the model from the GtkTreeView before it gets destroyed by the
|
||||
// wxDataViewCtrlBase's dtor
|
||||
gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview), NULL );
|
||||
|
||||
delete m_internal;
|
||||
}
|
||||
|
||||
void wxDataViewCtrl::Init()
|
||||
{
|
||||
m_notifier = NULL;
|
||||
m_internal = NULL;
|
||||
|
||||
m_cols.DeleteContents( true );
|
||||
@ -4492,18 +4532,7 @@ bool wxDataViewCtrl::AssociateModel( wxDataViewModel *model )
|
||||
}
|
||||
#endif
|
||||
|
||||
GtkWxTreeModel *gtk_model = wxgtk_tree_model_new();
|
||||
m_internal = new wxDataViewCtrlInternal( this, model, gtk_model );
|
||||
gtk_model->internal = m_internal;
|
||||
|
||||
m_notifier = new wxGtkDataViewModelNotifier( gtk_model, model, this );
|
||||
|
||||
model->AddNotifier( m_notifier );
|
||||
|
||||
gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview), GTK_TREE_MODEL(gtk_model) );
|
||||
|
||||
// unref in wxDataViewCtrlInternal
|
||||
// g_object_unref( gtk_model );
|
||||
m_internal = new wxDataViewCtrlInternal( this, model );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user