Don't send events when changing model in wxGTK wxDataViewCtrl
Sending events from e.g. AssociateModel(NULL) made the GTK version inconsistent with the other ones, neither of which sent any events in this case, and could result in a lot of grief in the user code if it didn't expect the event handler to be called at this moment (e.g. during the destruction). Make wxGTK compatible with the other ports and safer by always disabling the selection changed events before calling gtk_tree_view_set_model(). Note that it's still incompatible with the other ports because they also preserve the selection even after the change of model, but wxGTK loses it. Ideally this would be fixed too, but for now live with this as the lesser evil.
This commit is contained in:
@@ -250,6 +250,11 @@ public:
|
||||
}
|
||||
|
||||
|
||||
// Associate our model with the tree view or disassociate it from it
|
||||
// without generating any selection changed events, unlike
|
||||
// gtk_tree_view_set_model() that this function wraps.
|
||||
void UseModel(bool use);
|
||||
|
||||
// accessors
|
||||
wxDataViewModel* GetDataViewModel() { return m_wx_model; }
|
||||
const wxDataViewModel* GetDataViewModel() const { return m_wx_model; }
|
||||
@@ -1865,20 +1870,16 @@ bool wxGtkDataViewModelNotifier::ValueChanged( const wxDataViewItem &item, unsig
|
||||
|
||||
bool wxGtkDataViewModelNotifier::BeforeReset()
|
||||
{
|
||||
GtkWidget *treeview = m_internal->GetOwner()->GtkGetTreeView();
|
||||
gtk_tree_view_set_model( GTK_TREE_VIEW(treeview), NULL );
|
||||
m_internal->UseModel(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxGtkDataViewModelNotifier::AfterReset()
|
||||
{
|
||||
GtkWidget *treeview = m_internal->GetOwner()->GtkGetTreeView();
|
||||
GtkWxTreeModel *wxgtk_model = m_internal->GetGtkModel();
|
||||
|
||||
m_internal->Cleared();
|
||||
|
||||
gtk_tree_view_set_model( GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(wxgtk_model) );
|
||||
m_internal->UseModel(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -3551,7 +3552,7 @@ wxDataViewCtrlInternal::wxDataViewCtrlInternal( wxDataViewCtrl *owner, wxDataVie
|
||||
if (!m_wx_model->IsVirtualListModel())
|
||||
InitTree();
|
||||
|
||||
gtk_tree_view_set_model( GTK_TREE_VIEW(m_owner->GtkGetTreeView()), GTK_TREE_MODEL(m_gtk_model) );
|
||||
UseModel(true);
|
||||
}
|
||||
|
||||
wxDataViewCtrlInternal::~wxDataViewCtrlInternal()
|
||||
@@ -3559,7 +3560,7 @@ 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 );
|
||||
UseModel(false);
|
||||
|
||||
g_object_unref( m_gtk_model );
|
||||
|
||||
@@ -3568,6 +3569,18 @@ wxDataViewCtrlInternal::~wxDataViewCtrlInternal()
|
||||
delete m_dropDataObject;
|
||||
}
|
||||
|
||||
void wxDataViewCtrlInternal::UseModel(bool use)
|
||||
{
|
||||
// Avoid any selection changed events from gtk_tree_view_set_model() call
|
||||
// below as they don't happen under the other platforms and can be
|
||||
// unexpected with the possibly fatal consequences for the user-defined
|
||||
// event handler.
|
||||
wxDataViewCtrl::SelectionEventsSuppressor noSelection(m_owner);
|
||||
|
||||
gtk_tree_view_set_model( GTK_TREE_VIEW(m_owner->GtkGetTreeView()),
|
||||
use ? GTK_TREE_MODEL(m_gtk_model) : NULL );
|
||||
}
|
||||
|
||||
void wxDataViewCtrlInternal::ScheduleRefresh()
|
||||
{
|
||||
m_dirty = true;
|
||||
|
Reference in New Issue
Block a user