1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/gtk/dataview.cpp 
   3 // Purpose:     wxDataViewCtrl GTK+2 implementation 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  10 // For compilers that support precompilation, includes "wx.h". 
  11 #include "wx/wxprec.h" 
  13 #if wxUSE_DATAVIEWCTRL 
  15 #include "wx/dataview.h" 
  17 #ifndef wxUSE_GENERICDATAVIEWCTRL 
  21     #include "wx/dcclient.h" 
  23     #include "wx/settings.h" 
  27 #include "wx/stockitem.h" 
  28 #include "wx/calctrl.h" 
  29 #include "wx/popupwin.h" 
  30 #include "wx/listimpl.cpp" 
  32 #include "wx/gtk/private.h" 
  33 #include "wx/gtk/dc.h" 
  34 #include "wx/gtk/dcclient.h" 
  36 #include "wx/gtk/private/gdkconv.h" 
  37 using namespace wxGTKImpl
; 
  39 class wxGtkDataViewModelNotifier
; 
  41 //----------------------------------------------------------------------------- 
  42 //----------------------------------------------------------------------------- 
  44 static wxDataViewCtrlInternal 
*gs_internal 
= NULL
; 
  46 class wxGtkTreeModelNode
; 
  49 typedef struct _GtkWxTreeModel       GtkWxTreeModel
; 
  52 // ---------------------------------------------------------------------------- 
  53 // wxGtkTreePath: self-destroying GtkTreePath 
  54 // ---------------------------------------------------------------------------- 
  56 // Usually this object is initialized with the associated GtkTreePath 
  57 // immediately when it's constructed but it can also be changed later either by 
  58 // using Assign() or by getting the pointer to the internally stored pointer 
  59 // value using ByRef(). The latter should be avoided but is very convenient 
  60 // when using GTK functions with GtkTreePath output parameters. 
  64     // Ctor takes ownership of the given path and will free it if non-NULL. 
  65     wxGtkTreePath(GtkTreePath 
*path 
= NULL
) : m_path(path
) { } 
  67     // Creates a tree path for the given string path. 
  68     wxGtkTreePath(const gchar 
*strpath
) 
  69         : m_path(gtk_tree_path_new_from_string(strpath
)) 
  73     // Set the stored pointer if not done by ctor. 
  74     void Assign(GtkTreePath 
*path
) 
  76         wxASSERT_MSG( !m_path
, "shouldn't be already initialized" ); 
  81     // Return the pointer to the internally stored pointer. This should only be 
  82     // used to initialize the object by passing it to some GTK function. 
  85         wxASSERT_MSG( !m_path
, "shouldn't be already initialized" ); 
  91     operator GtkTreePath 
*() const { return m_path
; } 
  93     ~wxGtkTreePath() { if ( m_path 
) gtk_tree_path_free(m_path
); } 
  98     wxDECLARE_NO_COPY_CLASS(wxGtkTreePath
); 
 101 // ---------------------------------------------------------------------------- 
 102 // wxGtkTreeSelectionLock: prevent selection from changing during the 
 103 //                                 lifetime of this object 
 104 // ---------------------------------------------------------------------------- 
 106 // Implementation note: it could be expected that setting the selection 
 107 // function in this class ctor and resetting it back to the old value in its 
 108 // dtor would work. However currently gtk_tree_selection_get_select_function() 
 109 // can't be passed NULL (see https://bugzilla.gnome.org/show_bug.cgi?id=626276) 
 110 // so we can't do this. Instead, we always use the selection function (which 
 111 // imposes extra overhead, albeit minimal one, on all selection operations) and 
 112 // just set/reset the flag telling it whether it should allow or forbid the 
 115 // Also notice that currently only a single object of this class may exist at 
 116 // any given moment. It's just simpler like this and we don't need anything 
 120 gboolean 
wxdataview_selection_func(GtkTreeSelection 
* WXUNUSED(selection
), 
 121                                    GtkTreeModel 
* WXUNUSED(model
), 
 122                                    GtkTreePath 
* WXUNUSED(path
), 
 123                                    gboolean 
WXUNUSED(path_currently_selected
), 
 129 class wxGtkTreeSelectionLock
 
 132     wxGtkTreeSelectionLock(GtkTreeSelection 
*selection
) 
 133         : m_selection(selection
) 
 135         wxASSERT_MSG( !ms_instance
, "this class is not reentrant currently" ); 
 139         CheckCurrentSelectionFunc(NULL
); 
 141         // Pass some non-NULL pointer as "data" for the callback, it doesn't 
 142         // matter what it is as long as it's non-NULL. 
 143         gtk_tree_selection_set_select_function(selection
, 
 144                                                wxdataview_selection_func
, 
 149     ~wxGtkTreeSelectionLock() 
 151         CheckCurrentSelectionFunc(wxdataview_selection_func
); 
 153         gtk_tree_selection_set_select_function(m_selection
, 
 154                                                wxdataview_selection_func
, 
 162     void CheckCurrentSelectionFunc(GtkTreeSelectionFunc func
) 
 164         // We can only use gtk_tree_selection_get_select_function() with 2.14+ 
 165         // so check for its availability both during compile- and run-time. 
 166 #if GTK_CHECK_VERSION(2, 14, 0) 
 167         if ( gtk_check_version(2, 14, 0) != NULL 
) 
 170         // If this assert is triggered, it means the code elsewhere has called 
 171         // gtk_tree_selection_set_select_function() but currently doing this 
 172         // breaks this class so the code here needs to be changed. 
 175             gtk_tree_selection_get_select_function(m_selection
) == func
, 
 176             "selection function has changed unexpectedly, review this code!" 
 183     static wxGtkTreeSelectionLock 
*ms_instance
; 
 185     GtkTreeSelection 
* const m_selection
; 
 187     wxDECLARE_NO_COPY_CLASS(wxGtkTreeSelectionLock
); 
 190 wxGtkTreeSelectionLock 
*wxGtkTreeSelectionLock::ms_instance 
= NULL
; 
 192 //----------------------------------------------------------------------------- 
 193 // wxDataViewCtrlInternal 
 194 //----------------------------------------------------------------------------- 
 196 WX_DECLARE_LIST(wxDataViewItem
, ItemList
); 
 197 WX_DEFINE_LIST(ItemList
) 
 199 class wxDataViewCtrlInternal
 
 202     wxDataViewCtrlInternal( wxDataViewCtrl 
*owner
, wxDataViewModel 
*wx_model 
); 
 203     ~wxDataViewCtrlInternal(); 
 206     GtkTreeModelFlags 
get_flags(); 
 207     gboolean 
get_iter( GtkTreeIter 
*iter
, GtkTreePath 
*path 
); 
 208     GtkTreePath 
*get_path( GtkTreeIter 
*iter
); 
 209     gboolean 
iter_next( GtkTreeIter 
*iter 
); 
 210     gboolean 
iter_children( GtkTreeIter 
*iter
, GtkTreeIter 
*parent
); 
 211     gboolean 
iter_has_child( GtkTreeIter 
*iter 
); 
 212     gint 
iter_n_children( GtkTreeIter 
*iter 
); 
 213     gboolean 
iter_nth_child( GtkTreeIter 
*iter
, GtkTreeIter 
*parent
, gint n 
); 
 214     gboolean 
iter_parent( GtkTreeIter 
*iter
, GtkTreeIter 
*child 
); 
 218     bool EnableDragSource( const wxDataFormat 
&format 
); 
 219     bool EnableDropTarget( const wxDataFormat 
&format 
); 
 221     gboolean 
row_draggable( GtkTreeDragSource 
*drag_source
, GtkTreePath 
*path 
); 
 222     gboolean 
drag_data_delete( GtkTreeDragSource 
*drag_source
, GtkTreePath
* path 
); 
 223     gboolean 
drag_data_get( GtkTreeDragSource 
*drag_source
, GtkTreePath 
*path
, 
 224         GtkSelectionData 
*selection_data 
); 
 225     gboolean 
drag_data_received( GtkTreeDragDest 
*drag_dest
, GtkTreePath 
*dest
, 
 226         GtkSelectionData 
*selection_data 
); 
 227     gboolean 
row_drop_possible( GtkTreeDragDest 
*drag_dest
, GtkTreePath 
*dest_path
, 
 228         GtkSelectionData 
*selection_data 
); 
 230     // notifactions from wxDataViewModel 
 231     bool ItemAdded( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
); 
 232     bool ItemDeleted( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
); 
 233     bool ItemChanged( const wxDataViewItem 
&item 
); 
 234     bool ValueChanged( const wxDataViewItem 
&item
, unsigned int col 
); 
 241     void SetSortOrder( GtkSortType sort_order 
) { m_sort_order 
= sort_order
; } 
 242     GtkSortType 
GetSortOrder() const            { return m_sort_order
; } 
 244     void SetSortColumn( int column 
)            { m_sort_column 
= column
; } 
 245     int GetSortColumn() const                   { return m_sort_column
; } 
 247     void SetDataViewSortColumn( wxDataViewColumn 
*column 
) { m_dataview_sort_column 
= column
; } 
 248     wxDataViewColumn 
*GetDataViewSortColumn()   { return m_dataview_sort_column
; } 
 250     bool IsSorted()                             { return (m_sort_column 
>= 0); } 
 253     wxDataViewModel
* GetDataViewModel() { return m_wx_model
; } 
 254     const wxDataViewModel
* GetDataViewModel() const { return m_wx_model
; } 
 255     wxDataViewCtrl
* GetOwner()          { return m_owner
; } 
 256     GtkWxTreeModel
* GetGtkModel()       { return m_gtk_model
; } 
 258     // item can be deleted already in the model 
 259     int GetIndexOf( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
); 
 261     virtual void OnInternalIdle(); 
 265     void ScheduleRefresh(); 
 267     wxGtkTreeModelNode 
*FindNode( const wxDataViewItem 
&item 
); 
 268     wxGtkTreeModelNode 
*FindNode( GtkTreeIter 
*iter 
); 
 269     wxGtkTreeModelNode 
*FindParentNode( const wxDataViewItem 
&item 
); 
 270     wxGtkTreeModelNode 
*FindParentNode( GtkTreeIter 
*iter 
); 
 271     void BuildBranch( wxGtkTreeModelNode 
*branch 
); 
 274     wxGtkTreeModelNode   
*m_root
; 
 275     wxDataViewModel      
*m_wx_model
; 
 276     GtkWxTreeModel       
*m_gtk_model
; 
 277     wxDataViewCtrl       
*m_owner
; 
 278     GtkSortType           m_sort_order
; 
 279     wxDataViewColumn     
*m_dataview_sort_column
; 
 282     GtkTargetEntry        m_dragSourceTargetEntry
; 
 283     wxCharBuffer          m_dragSourceTargetEntryTarget
; 
 284     wxDataObject         
*m_dragDataObject
; 
 286     GtkTargetEntry        m_dropTargetTargetEntry
; 
 287     wxCharBuffer          m_dropTargetTargetEntryTarget
; 
 288     wxDataObject         
*m_dropDataObject
; 
 290     wxGtkDataViewModelNotifier 
*m_notifier
; 
 296 //----------------------------------------------------------------------------- 
 297 // wxGtkTreeModelNode 
 298 //----------------------------------------------------------------------------- 
 301 int LINKAGEMODE 
wxGtkTreeModelChildCmp( void** id1
, void** id2 
) 
 303     int ret 
= gs_internal
->GetDataViewModel()->Compare( *id1
, *id2
, 
 304         gs_internal
->GetSortColumn(), (gs_internal
->GetSortOrder() == GTK_SORT_ASCENDING
) ); 
 309 WX_DEFINE_ARRAY_PTR( wxGtkTreeModelNode
*, wxGtkTreeModelNodes 
); 
 310 WX_DEFINE_ARRAY_PTR( void*, wxGtkTreeModelChildren 
); 
 312 class wxGtkTreeModelNode
 
 315     wxGtkTreeModelNode( wxGtkTreeModelNode
* parent
, const wxDataViewItem 
&item
, 
 316                         wxDataViewCtrlInternal 
*internal 
) 
 320         m_internal 
= internal
; 
 323     ~wxGtkTreeModelNode() 
 325         size_t count 
= m_nodes
.GetCount(); 
 327         for (i 
= 0; i 
< count
; i
++) 
 329             wxGtkTreeModelNode 
*child 
= m_nodes
.Item( i 
); 
 334     unsigned int AddNode( wxGtkTreeModelNode
* child 
) 
 336             m_nodes
.Add( child 
); 
 338             void *id 
= child
->GetItem().GetID(); 
 340             m_children
.Add( id 
); 
 342             if (m_internal
->IsSorted() || m_internal
->GetDataViewModel()->HasDefaultCompare()) 
 344                 gs_internal 
= m_internal
; 
 345                 m_children
.Sort( &wxGtkTreeModelChildCmp 
); 
 346                 return m_children
.Index( id 
); 
 349             return m_children
.GetCount()-1; 
 352     unsigned int AddLeave( void* id 
) 
 354             m_children
.Add( id 
); 
 356             if (m_internal
->IsSorted() || m_internal
->GetDataViewModel()->HasDefaultCompare()) 
 358                 gs_internal 
= m_internal
; 
 359                 m_children
.Sort( &wxGtkTreeModelChildCmp 
); 
 360                 return m_children
.Index( id 
); 
 363             return m_children
.GetCount()-1; 
 366     void DeleteChild( void* id 
) 
 368             m_children
.Remove( id 
); 
 370             unsigned int count 
= m_nodes
.GetCount(); 
 372             for (pos 
= 0; pos 
< count
; pos
++) 
 374                 wxGtkTreeModelNode 
*node 
= m_nodes
.Item( pos 
); 
 375                 if (node
->GetItem().GetID() == id
) 
 377                     m_nodes
.RemoveAt( pos 
); 
 384     wxGtkTreeModelNode
* GetParent() 
 386     wxGtkTreeModelNodes 
&GetNodes() 
 388     wxGtkTreeModelChildren 
&GetChildren() 
 389         { return m_children
; } 
 391     unsigned int GetChildCount() const { return m_children
.GetCount(); } 
 392     unsigned int GetNodesCount() const { return m_nodes
.GetCount(); } 
 394     wxDataViewItem 
&GetItem() { return m_item
; } 
 395     wxDataViewCtrlInternal 
*GetInternal() { return m_internal
; } 
 400     wxGtkTreeModelNode         
*m_parent
; 
 401     wxGtkTreeModelNodes         m_nodes
; 
 402     wxGtkTreeModelChildren      m_children
; 
 403     wxDataViewItem              m_item
; 
 404     wxDataViewCtrlInternal     
*m_internal
; 
 408 //----------------------------------------------------------------------------- 
 410 //----------------------------------------------------------------------------- 
 412 extern bool   g_blockEventsOnDrag
; 
 414 //----------------------------------------------------------------------------- 
 415 // define new GTK+ class wxGtkTreeModel 
 416 //----------------------------------------------------------------------------- 
 420 #define GTK_TYPE_WX_TREE_MODEL               (gtk_wx_tree_model_get_type ()) 
 421 #define GTK_WX_TREE_MODEL(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModel)) 
 422 #define GTK_WX_TREE_MODEL_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModelClass)) 
 423 #define GTK_IS_WX_TREE_MODEL(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_TREE_MODEL)) 
 424 #define GTK_IS_WX_TREE_MODEL_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_TREE_MODEL)) 
 425 #define GTK_WX_TREE_MODEL_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModelClass)) 
 427 GType         
gtk_wx_tree_model_get_type         (void); 
 429 typedef struct _GtkWxTreeModelClass  GtkWxTreeModelClass
; 
 431 struct _GtkWxTreeModel
 
 437   wxDataViewCtrlInternal 
*internal
; 
 440 struct _GtkWxTreeModelClass
 
 442   GObjectClass list_parent_class
; 
 445 static GtkWxTreeModel 
*wxgtk_tree_model_new          (void); 
 446 static void         wxgtk_tree_model_init            (GtkWxTreeModel       
*tree_model
); 
 447 static void         wxgtk_tree_model_class_init      (GtkWxTreeModelClass  
*klass
); 
 449 static void         wxgtk_tree_model_tree_model_init (GtkTreeModelIface       
*iface
); 
 450 static void         wxgtk_tree_model_sortable_init   (GtkTreeSortableIface    
*iface
); 
 451 static void         wxgtk_tree_model_drag_source_init(GtkTreeDragSourceIface  
*iface
); 
 452 static void         wxgtk_tree_model_drag_dest_init  (GtkTreeDragDestIface    
*iface
); 
 454 static void         wxgtk_tree_model_finalize        (GObject           
*object
); 
 455 static GtkTreeModelFlags 
wxgtk_tree_model_get_flags  (GtkTreeModel      
*tree_model
); 
 456 static gint         
wxgtk_tree_model_get_n_columns   (GtkTreeModel      
*tree_model
); 
 457 static GType        
wxgtk_tree_model_get_column_type (GtkTreeModel      
*tree_model
, 
 459 static gboolean     
wxgtk_tree_model_get_iter        (GtkTreeModel      
*tree_model
, 
 462 static GtkTreePath 
*wxgtk_tree_model_get_path        (GtkTreeModel      
*tree_model
, 
 464 static void         wxgtk_tree_model_get_value       (GtkTreeModel      
*tree_model
, 
 468 static gboolean     
wxgtk_tree_model_iter_next       (GtkTreeModel      
*tree_model
, 
 470 static gboolean     
wxgtk_tree_model_iter_children   (GtkTreeModel      
*tree_model
, 
 472                                                       GtkTreeIter       
*parent
); 
 473 static gboolean     
wxgtk_tree_model_iter_has_child  (GtkTreeModel      
*tree_model
, 
 475 static gint         
wxgtk_tree_model_iter_n_children (GtkTreeModel      
*tree_model
, 
 477 static gboolean     
wxgtk_tree_model_iter_nth_child  (GtkTreeModel      
*tree_model
, 
 481 static gboolean     
wxgtk_tree_model_iter_parent     (GtkTreeModel      
*tree_model
, 
 486 static gboolean 
wxgtk_tree_model_get_sort_column_id    (GtkTreeSortable       
*sortable
, 
 487                                                         gint                  
*sort_column_id
, 
 489 static void     wxgtk_tree_model_set_sort_column_id    (GtkTreeSortable       
*sortable
, 
 492 static void     wxgtk_tree_model_set_sort_func         (GtkTreeSortable       
*sortable
, 
 494                                                         GtkTreeIterCompareFunc func
, 
 496                                                         GtkDestroyNotify       destroy
); 
 497 static void     wxgtk_tree_model_set_default_sort_func (GtkTreeSortable       
*sortable
, 
 498                                                         GtkTreeIterCompareFunc func
, 
 500                                                         GtkDestroyNotify       destroy
); 
 501 static gboolean 
wxgtk_tree_model_has_default_sort_func (GtkTreeSortable       
*sortable
); 
 504 static gboolean 
wxgtk_tree_model_row_draggable         (GtkTreeDragSource     
*drag_source
, 
 506 static gboolean 
wxgtk_tree_model_drag_data_delete      (GtkTreeDragSource     
*drag_source
, 
 508 static gboolean 
wxgtk_tree_model_drag_data_get         (GtkTreeDragSource     
*drag_source
, 
 510                                                         GtkSelectionData      
*selection_data
); 
 511 static gboolean 
wxgtk_tree_model_drag_data_received    (GtkTreeDragDest       
*drag_dest
, 
 513                                                         GtkSelectionData      
*selection_data
); 
 514 static gboolean 
wxgtk_tree_model_row_drop_possible     (GtkTreeDragDest       
*drag_dest
, 
 515                                                         GtkTreePath           
*dest_path
, 
 516                                                         GtkSelectionData      
*selection_data
); 
 519 static GObjectClass 
*list_parent_class 
= NULL
; 
 522 gtk_wx_tree_model_get_type (void) 
 524     static GType tree_model_type 
= 0; 
 526     if (!tree_model_type
) 
 528         const GTypeInfo tree_model_info 
= 
 530             sizeof (GtkWxTreeModelClass
), 
 531             NULL
,   /* base_init */ 
 532             NULL
,   /* base_finalize */ 
 533             (GClassInitFunc
) wxgtk_tree_model_class_init
, 
 534             NULL
,   /* class_finalize */ 
 535             NULL
,   /* class_data */ 
 536             sizeof (GtkWxTreeModel
), 
 538             (GInstanceInitFunc
) wxgtk_tree_model_init
, 
 541         static const GInterfaceInfo tree_model_iface_info 
= 
 543             (GInterfaceInitFunc
) wxgtk_tree_model_tree_model_init
, 
 548         static const GInterfaceInfo sortable_iface_info 
= 
 550             (GInterfaceInitFunc
) wxgtk_tree_model_sortable_init
, 
 555         static const GInterfaceInfo drag_source_iface_info 
= 
 557             (GInterfaceInitFunc
) wxgtk_tree_model_drag_source_init
, 
 562         static const GInterfaceInfo drag_dest_iface_info 
= 
 564             (GInterfaceInitFunc
) wxgtk_tree_model_drag_dest_init
, 
 569         tree_model_type 
= g_type_register_static (G_TYPE_OBJECT
, "GtkWxTreeModel", 
 570                                                 &tree_model_info
, (GTypeFlags
)0 ); 
 572         g_type_add_interface_static (tree_model_type
, 
 574                                      &tree_model_iface_info
); 
 575         g_type_add_interface_static (tree_model_type
, 
 576                                      GTK_TYPE_TREE_SORTABLE
, 
 577                                      &sortable_iface_info
); 
 578         g_type_add_interface_static (tree_model_type
, 
 579                                      GTK_TYPE_TREE_DRAG_DEST
, 
 580                                      &drag_dest_iface_info
); 
 581         g_type_add_interface_static (tree_model_type
, 
 582                                      GTK_TYPE_TREE_DRAG_SOURCE
, 
 583                                      &drag_source_iface_info
); 
 586     return tree_model_type
; 
 589 static GtkWxTreeModel 
* 
 590 wxgtk_tree_model_new(void) 
 592     GtkWxTreeModel 
*retval 
= (GtkWxTreeModel 
*) g_object_new (GTK_TYPE_WX_TREE_MODEL
, NULL
); 
 597 wxgtk_tree_model_class_init (GtkWxTreeModelClass 
*klass
) 
 599     list_parent_class 
= (GObjectClass
*) g_type_class_peek_parent (klass
); 
 600     GObjectClass 
*object_class 
= (GObjectClass
*) klass
; 
 601     object_class
->finalize 
= wxgtk_tree_model_finalize
; 
 605 wxgtk_tree_model_tree_model_init (GtkTreeModelIface 
*iface
) 
 607     iface
->get_flags 
= wxgtk_tree_model_get_flags
; 
 608     iface
->get_n_columns 
= wxgtk_tree_model_get_n_columns
; 
 609     iface
->get_column_type 
= wxgtk_tree_model_get_column_type
; 
 610     iface
->get_iter 
= wxgtk_tree_model_get_iter
; 
 611     iface
->get_path 
= wxgtk_tree_model_get_path
; 
 612     iface
->get_value 
= wxgtk_tree_model_get_value
; 
 613     iface
->iter_next 
= wxgtk_tree_model_iter_next
; 
 614     iface
->iter_children 
= wxgtk_tree_model_iter_children
; 
 615     iface
->iter_has_child 
= wxgtk_tree_model_iter_has_child
; 
 616     iface
->iter_n_children 
= wxgtk_tree_model_iter_n_children
; 
 617     iface
->iter_nth_child 
= wxgtk_tree_model_iter_nth_child
; 
 618     iface
->iter_parent 
= wxgtk_tree_model_iter_parent
; 
 622 wxgtk_tree_model_sortable_init (GtkTreeSortableIface 
*iface
) 
 624     iface
->get_sort_column_id 
= wxgtk_tree_model_get_sort_column_id
; 
 625     iface
->set_sort_column_id 
= wxgtk_tree_model_set_sort_column_id
; 
 626     iface
->set_sort_func 
= wxgtk_tree_model_set_sort_func
; 
 627     iface
->set_default_sort_func 
= wxgtk_tree_model_set_default_sort_func
; 
 628     iface
->has_default_sort_func 
= wxgtk_tree_model_has_default_sort_func
; 
 632 wxgtk_tree_model_drag_source_init(GtkTreeDragSourceIface  
*iface
) 
 634     iface
->row_draggable 
= wxgtk_tree_model_row_draggable
; 
 635     iface
->drag_data_delete 
= wxgtk_tree_model_drag_data_delete
; 
 636     iface
->drag_data_get 
= wxgtk_tree_model_drag_data_get
; 
 640 wxgtk_tree_model_drag_dest_init  (GtkTreeDragDestIface    
*iface
) 
 642     iface
->drag_data_received 
= wxgtk_tree_model_drag_data_received
; 
 643     iface
->row_drop_possible 
= wxgtk_tree_model_row_drop_possible
; 
 647 wxgtk_tree_model_init (GtkWxTreeModel 
*tree_model
) 
 649     tree_model
->internal 
= NULL
; 
 650     tree_model
->stamp 
= g_random_int(); 
 654 wxgtk_tree_model_finalize (GObject 
*object
) 
 657     (* list_parent_class
->finalize
) (object
); 
 662 //----------------------------------------------------------------------------- 
 663 // implement callbacks from wxGtkTreeModel class by letting 
 664 // them call the methods of wxWidgets' wxDataViewModel 
 665 //----------------------------------------------------------------------------- 
 667 static GtkTreeModelFlags
 
 668 wxgtk_tree_model_get_flags (GtkTreeModel 
*tree_model
) 
 670     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 671     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), (GtkTreeModelFlags
)0 ); 
 673     return wxtree_model
->internal
->get_flags(); 
 677 wxgtk_tree_model_get_n_columns (GtkTreeModel 
*tree_model
) 
 679     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 680     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), 0); 
 682     return wxtree_model
->internal
->GetDataViewModel()->GetColumnCount(); 
 686 wxgtk_tree_model_get_column_type (GtkTreeModel 
*tree_model
, 
 689     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 690     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), G_TYPE_INVALID
); 
 692     GType gtype 
= G_TYPE_INVALID
; 
 694     wxString wxtype 
= wxtree_model
->internal
->GetDataViewModel()->GetColumnType( (unsigned int) index 
); 
 696     if (wxtype 
== wxT("string")) 
 697         gtype 
= G_TYPE_STRING
; 
 700         gtype 
= G_TYPE_POINTER
; 
 701         // wxFAIL_MSG( wxT("non-string columns not supported for searching yet") ); 
 708 wxgtk_tree_model_get_iter (GtkTreeModel 
*tree_model
, 
 712     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 713     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 714     g_return_val_if_fail (gtk_tree_path_get_depth (path
) > 0, FALSE
); 
 716     return wxtree_model
->internal
->get_iter( iter
, path 
); 
 720 wxgtk_tree_model_get_path (GtkTreeModel 
*tree_model
, 
 723     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 724     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), NULL
); 
 725     g_return_val_if_fail (iter
->stamp 
== GTK_WX_TREE_MODEL (wxtree_model
)->stamp
, NULL
); 
 727     return wxtree_model
->internal
->get_path( iter 
); 
 731 wxgtk_tree_model_get_value (GtkTreeModel 
*tree_model
, 
 736     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 737     g_return_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
) ); 
 739     wxDataViewModel 
*model 
= wxtree_model
->internal
->GetDataViewModel(); 
 740     wxString mtype 
= model
->GetColumnType( (unsigned int) column 
); 
 741     if (mtype 
== wxT("string")) 
 744         g_value_init( value
, G_TYPE_STRING 
); 
 745         wxDataViewItem 
item( (void*) iter
->user_data 
); 
 746         model
->GetValue( variant
, item
, (unsigned int) column 
); 
 748         g_value_set_string( value
, variant
.GetString().utf8_str() ); 
 752         wxFAIL_MSG( wxT("non-string columns not supported yet") ); 
 757 wxgtk_tree_model_iter_next (GtkTreeModel  
*tree_model
, 
 760     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 762     // This happens when clearing the view by calling .._set_model( NULL ); 
 763     if (iter
->stamp 
== 0) return FALSE
; 
 765     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 766     g_return_val_if_fail (wxtree_model
->stamp 
== iter
->stamp
, FALSE
); 
 768     return wxtree_model
->internal
->iter_next( iter 
); 
 772 wxgtk_tree_model_iter_children (GtkTreeModel 
*tree_model
, 
 776     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 777     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 780         g_return_val_if_fail (wxtree_model
->stamp 
== parent
->stamp
, FALSE
); 
 783     return wxtree_model
->internal
->iter_children( iter
, parent 
); 
 787 wxgtk_tree_model_iter_has_child (GtkTreeModel 
*tree_model
, 
 790     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 791     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 792     g_return_val_if_fail (wxtree_model
->stamp 
== iter
->stamp
, FALSE
); 
 794     return wxtree_model
->internal
->iter_has_child( iter 
); 
 798 wxgtk_tree_model_iter_n_children (GtkTreeModel 
*tree_model
, 
 801     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 802     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), 0); 
 803     g_return_val_if_fail ( !iter 
|| wxtree_model
->stamp 
== iter
->stamp
, 0); 
 805     return wxtree_model
->internal
->iter_n_children( iter 
); 
 809 wxgtk_tree_model_iter_nth_child (GtkTreeModel 
*tree_model
, 
 814     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 815     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 817     return wxtree_model
->internal
->iter_nth_child( iter
, parent
, n 
); 
 821 wxgtk_tree_model_iter_parent (GtkTreeModel 
*tree_model
, 
 825     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 826     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 827     g_return_val_if_fail (wxtree_model
->stamp 
== child
->stamp
, FALSE
); 
 829     return wxtree_model
->internal
->iter_parent( iter
, child 
); 
 832 /* drag'n'drop iface */ 
 834 wxgtk_tree_model_row_draggable (GtkTreeDragSource 
*drag_source
, 
 837     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) drag_source
; 
 838     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 840     return wxtree_model
->internal
->row_draggable( drag_source
, path 
); 
 844 wxgtk_tree_model_drag_data_delete (GtkTreeDragSource 
*drag_source
, 
 847     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) drag_source
; 
 848     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 850     return wxtree_model
->internal
->drag_data_delete( drag_source
, path 
); 
 854 wxgtk_tree_model_drag_data_get (GtkTreeDragSource 
*drag_source
, 
 856                                 GtkSelectionData  
*selection_data
) 
 858     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) drag_source
; 
 859     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 862     wxPrintf( "drag_get_data\n"); 
 864     wxGtkString 
atom_selection(gdk_atom_name(selection_data
->selection
)); 
 865     wxPrintf( "selection %s\n", wxString::FromAscii(atom_selection
) ); 
 867     wxGtkString 
atom_target(gdk_atom_name(selection_data
->target
)); 
 868     wxPrintf( "target %s\n", wxString::FromAscii(atom_target
) ); 
 870     wxGtkString 
atom_type(gdk_atom_name(selection_data
->type
)); 
 871     wxPrintf( "type %s\n", wxString::FromAscii(atom_type
) ); 
 873     wxPrintf( "format %d\n", selection_data
->format 
); 
 876     return wxtree_model
->internal
->drag_data_get( drag_source
, path
, selection_data 
); 
 880 wxgtk_tree_model_drag_data_received (GtkTreeDragDest  
*drag_dest
, 
 882                                      GtkSelectionData 
*selection_data
) 
 884     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) drag_dest
; 
 885     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 887     return wxtree_model
->internal
->drag_data_received( drag_dest
, dest
, selection_data 
); 
 891 wxgtk_tree_model_row_drop_possible (GtkTreeDragDest  
*drag_dest
, 
 892                                     GtkTreePath      
*dest_path
, 
 893                                     GtkSelectionData 
*selection_data
) 
 895     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) drag_dest
; 
 896     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 898     return wxtree_model
->internal
->row_drop_possible( drag_dest
, dest_path
, selection_data 
); 
 903 wxgtk_tree_model_get_sort_column_id (GtkTreeSortable 
*sortable
, 
 904                                      gint            
*sort_column_id
, 
 907     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) sortable
; 
 909     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (sortable
), FALSE
); 
 911     if (!wxtree_model
->internal
->IsSorted()) 
 914             *sort_column_id 
= -1; 
 921         *sort_column_id 
= wxtree_model
->internal
->GetSortColumn(); 
 924         *order 
= wxtree_model
->internal
->GetSortOrder(); 
 929 wxDataViewColumn 
*gs_lastLeftClickHeader 
= NULL
; 
 932 wxgtk_tree_model_set_sort_column_id (GtkTreeSortable 
*sortable
, 
 936     GtkWxTreeModel 
*tree_model 
= (GtkWxTreeModel 
*) sortable
; 
 937     g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable
) ); 
 939     tree_model
->internal
->SetDataViewSortColumn( gs_lastLeftClickHeader 
); 
 941     if ((sort_column_id 
!= (gint
) tree_model
->internal
->GetSortColumn()) || 
 942         (order 
!= tree_model
->internal
->GetSortOrder())) 
 944         tree_model
->internal
->SetSortColumn( sort_column_id 
); 
 945         tree_model
->internal
->SetSortOrder( order 
); 
 947         gtk_tree_sortable_sort_column_changed (sortable
); 
 949         tree_model
->internal
->GetDataViewModel()->Resort(); 
 952     if (gs_lastLeftClickHeader
) 
 954         wxDataViewCtrl 
*dv 
= tree_model
->internal
->GetOwner(); 
 955         wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED
, dv
->GetId() ); 
 956         event
.SetDataViewColumn( gs_lastLeftClickHeader 
); 
 957         event
.SetModel( dv
->GetModel() ); 
 958         dv
->HandleWindowEvent( event 
); 
 961     gs_lastLeftClickHeader 
= NULL
; 
 965 wxgtk_tree_model_set_sort_func (GtkTreeSortable        
*sortable
, 
 966                                 gint                    
WXUNUSED(sort_column_id
), 
 967                                 GtkTreeIterCompareFunc  func
, 
 968                                 gpointer                
WXUNUSED(data
), 
 969                                 GtkDestroyNotify        
WXUNUSED(destroy
)) 
 971     g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable
) ); 
 972     g_return_if_fail (func 
!= NULL
); 
 976 wxgtk_tree_model_set_default_sort_func (GtkTreeSortable          
*sortable
, 
 977                                         GtkTreeIterCompareFunc    func
, 
 978                                         gpointer                  
WXUNUSED(data
), 
 979                                         GtkDestroyNotify          
WXUNUSED(destroy
)) 
 981     g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable
) ); 
 982     g_return_if_fail (func 
!= NULL
); 
 984     //wxPrintf( "wxgtk_tree_model_set_default_sort_func\n" ); 
 985     // TODO: remove this code 
 989 wxgtk_tree_model_has_default_sort_func (GtkTreeSortable        
*sortable
) 
 991     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (sortable
), FALSE 
); 
 996 //----------------------------------------------------------------------------- 
 997 // define new GTK+ class GtkWxRendererText 
 998 //----------------------------------------------------------------------------- 
1002 #define GTK_TYPE_WX_CELL_RENDERER_TEXT               (gtk_wx_cell_renderer_text_get_type ()) 
1003 #define GTK_WX_CELL_RENDERER_TEXT(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_CELL_RENDERER_TEXT, GtkWxCellRendererText)) 
1004 #define GTK_WX_CELL_RENDERER_TEXT_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_CELL_RENDERER_TEXT, GtkWxCellRendererTextClass)) 
1005 #define GTK_IS_WX_CELL_RENDERER_TEXT(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_CELL_RENDERER_TEXT)) 
1006 #define GTK_IS_WX_CELL_RENDERER_TEXT_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_CELL_RENDERER_TEXT)) 
1007 #define GTK_WX_CELL_RENDERER_TEXT_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_CELL_RENDERER_TEXT, GtkWxCellRendererTextClass)) 
1009 GType            
gtk_wx_cell_renderer_text_get_type (void); 
1011 typedef struct _GtkWxCellRendererText GtkWxCellRendererText
; 
1012 typedef struct _GtkWxCellRendererTextClass GtkWxCellRendererTextClass
; 
1014 struct _GtkWxCellRendererText
 
1016   GtkCellRendererText parent
; 
1018   wxDataViewRenderer 
*wx_renderer
; 
1021 struct _GtkWxCellRendererTextClass
 
1023   GtkCellRendererTextClass cell_parent_class
; 
1027 static GtkWxCellRendererText 
*gtk_wx_cell_renderer_text_new   (void); 
1028 static void gtk_wx_cell_renderer_text_init ( 
1029                         GtkWxCellRendererText      
*cell 
); 
1030 static void gtk_wx_cell_renderer_text_class_init( 
1031                         GtkWxCellRendererTextClass 
*klass 
); 
1032 static void gtk_wx_cell_renderer_text_finalize ( 
1034 static GtkCellEditable 
*gtk_wx_cell_renderer_text_start_editing( 
1035                         GtkCellRenderer         
*cell
, 
1039                         GdkRectangle            
*background_area
, 
1040                         GdkRectangle            
*cell_area
, 
1041                         GtkCellRendererState     flags 
); 
1044 static GObjectClass 
*text_cell_parent_class 
= NULL
; 
1049 gtk_wx_cell_renderer_text_get_type (void) 
1051     static GType cell_wx_type 
= 0; 
1055         const GTypeInfo cell_wx_info 
= 
1057             sizeof (GtkWxCellRendererTextClass
), 
1058             NULL
, /* base_init */ 
1059             NULL
, /* base_finalize */ 
1060             (GClassInitFunc
) gtk_wx_cell_renderer_text_class_init
, 
1061             NULL
, /* class_finalize */ 
1062             NULL
, /* class_data */ 
1063             sizeof (GtkWxCellRendererText
), 
1064             0,          /* n_preallocs */ 
1065             (GInstanceInitFunc
) gtk_wx_cell_renderer_text_init
, 
1068         cell_wx_type 
= g_type_register_static( GTK_TYPE_CELL_RENDERER_TEXT
, 
1069             "GtkWxCellRendererText", &cell_wx_info
, (GTypeFlags
)0 ); 
1072     return cell_wx_type
; 
1076 gtk_wx_cell_renderer_text_init (GtkWxCellRendererText 
*cell
) 
1078     cell
->wx_renderer 
= NULL
; 
1082 gtk_wx_cell_renderer_text_class_init (GtkWxCellRendererTextClass 
*klass
) 
1084     GObjectClass 
*object_class 
= G_OBJECT_CLASS (klass
); 
1085     GtkCellRendererClass 
*cell_class 
= GTK_CELL_RENDERER_CLASS (klass
); 
1087     text_cell_parent_class 
= (GObjectClass
*) g_type_class_peek_parent (klass
); 
1089     object_class
->finalize 
= gtk_wx_cell_renderer_text_finalize
; 
1091     cell_class
->start_editing 
= gtk_wx_cell_renderer_text_start_editing
; 
1095 gtk_wx_cell_renderer_text_finalize (GObject 
*object
) 
1098     (* G_OBJECT_CLASS (text_cell_parent_class
)->finalize
) (object
); 
1101 GtkWxCellRendererText
* 
1102 gtk_wx_cell_renderer_text_new (void) 
1104     return (GtkWxCellRendererText
*) g_object_new (GTK_TYPE_WX_CELL_RENDERER_TEXT
, NULL
); 
1107 static GtkCellEditable 
*gtk_wx_cell_renderer_text_start_editing( 
1108                         GtkCellRenderer         
*gtk_renderer
, 
1109                         GdkEvent                
*gdk_event
, 
1112                         GdkRectangle            
*background_area
, 
1113                         GdkRectangle            
*cell_area
, 
1114                         GtkCellRendererState     flags 
) 
1116     GtkWxCellRendererText 
*wxgtk_renderer 
= (GtkWxCellRendererText 
*) gtk_renderer
; 
1117     wxDataViewRenderer 
*wx_renderer 
= wxgtk_renderer
->wx_renderer
; 
1118     wxDataViewColumn 
*column 
= wx_renderer
->GetOwner(); 
1121         item(column
->GetOwner()->GTKPathToItem(wxGtkTreePath(path
))); 
1123     wxDataViewCtrl 
*dv 
= column
->GetOwner(); 
1124     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_START_EDITING
, dv
->GetId() ); 
1125     event
.SetDataViewColumn( column 
); 
1126     event
.SetModel( dv
->GetModel() ); 
1127     event
.SetColumn( column
->GetModelColumn() ); 
1128     event
.SetItem( item 
); 
1129     dv
->HandleWindowEvent( event 
); 
1131     if (event
.IsAllowed()) 
1132         return GTK_CELL_RENDERER_CLASS(text_cell_parent_class
)-> 
1133            start_editing( gtk_renderer
, gdk_event
, widget
, path
, background_area
, cell_area
, flags 
); 
1138 //----------------------------------------------------------------------------- 
1139 // define new GTK+ class GtkWxCellRenderer 
1140 //----------------------------------------------------------------------------- 
1144 #define GTK_TYPE_WX_CELL_RENDERER               (gtk_wx_cell_renderer_get_type ()) 
1145 #define GTK_WX_CELL_RENDERER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRenderer)) 
1146 #define GTK_WX_CELL_RENDERER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRendererClass)) 
1147 #define GTK_IS_WX_CELL_RENDERER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_CELL_RENDERER)) 
1148 #define GTK_IS_WX_CELL_RENDERER_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_CELL_RENDERER)) 
1149 #define GTK_WX_CELL_RENDERER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRendererClass)) 
1151 GType            
gtk_wx_cell_renderer_get_type (void); 
1153 typedef struct _GtkWxCellRenderer GtkWxCellRenderer
; 
1154 typedef struct _GtkWxCellRendererClass GtkWxCellRendererClass
; 
1156 struct _GtkWxCellRenderer
 
1158   GtkCellRenderer parent
; 
1161   wxDataViewCustomRenderer 
*cell
; 
1165 struct _GtkWxCellRendererClass
 
1167   GtkCellRendererClass cell_parent_class
; 
1171 static GtkCellRenderer 
*gtk_wx_cell_renderer_new   (void); 
1172 static void gtk_wx_cell_renderer_init ( 
1173                         GtkWxCellRenderer      
*cell 
); 
1174 static void gtk_wx_cell_renderer_class_init( 
1175                         GtkWxCellRendererClass 
*klass 
); 
1176 static void gtk_wx_cell_renderer_finalize ( 
1178 static void gtk_wx_cell_renderer_get_size ( 
1179                         GtkCellRenderer         
*cell
, 
1181                         GdkRectangle            
*rectangle
, 
1186 static void gtk_wx_cell_renderer_render ( 
1187                         GtkCellRenderer         
*cell
, 
1190                         GdkRectangle            
*background_area
, 
1191                         GdkRectangle            
*cell_area
, 
1192                         GdkRectangle            
*expose_area
, 
1193                         GtkCellRendererState     flags 
); 
1194 static gboolean 
gtk_wx_cell_renderer_activate( 
1195                         GtkCellRenderer         
*cell
, 
1199                         GdkRectangle            
*background_area
, 
1200                         GdkRectangle            
*cell_area
, 
1201                         GtkCellRendererState     flags 
); 
1202 static GtkCellEditable 
*gtk_wx_cell_renderer_start_editing( 
1203                         GtkCellRenderer         
*cell
, 
1207                         GdkRectangle            
*background_area
, 
1208                         GdkRectangle            
*cell_area
, 
1209                         GtkCellRendererState     flags 
); 
1212 static GObjectClass 
*cell_parent_class 
= NULL
; 
1217 gtk_wx_cell_renderer_get_type (void) 
1219     static GType cell_wx_type 
= 0; 
1223         const GTypeInfo cell_wx_info 
= 
1225             sizeof (GtkWxCellRendererClass
), 
1226             NULL
, /* base_init */ 
1227             NULL
, /* base_finalize */ 
1228             (GClassInitFunc
) gtk_wx_cell_renderer_class_init
, 
1229             NULL
, /* class_finalize */ 
1230             NULL
, /* class_data */ 
1231             sizeof (GtkWxCellRenderer
), 
1232             0,          /* n_preallocs */ 
1233             (GInstanceInitFunc
) gtk_wx_cell_renderer_init
, 
1236         cell_wx_type 
= g_type_register_static( GTK_TYPE_CELL_RENDERER
, 
1237             "GtkWxCellRenderer", &cell_wx_info
, (GTypeFlags
)0 ); 
1240     return cell_wx_type
; 
1244 gtk_wx_cell_renderer_init (GtkWxCellRenderer 
*cell
) 
1247     cell
->last_click 
= 0; 
1251 gtk_wx_cell_renderer_class_init (GtkWxCellRendererClass 
*klass
) 
1253     GObjectClass 
*object_class 
= G_OBJECT_CLASS (klass
); 
1254     GtkCellRendererClass 
*cell_class 
= GTK_CELL_RENDERER_CLASS (klass
); 
1256     cell_parent_class 
= (GObjectClass
*) g_type_class_peek_parent (klass
); 
1258     object_class
->finalize 
= gtk_wx_cell_renderer_finalize
; 
1260     cell_class
->get_size 
= gtk_wx_cell_renderer_get_size
; 
1261     cell_class
->render 
= gtk_wx_cell_renderer_render
; 
1262     cell_class
->activate 
= gtk_wx_cell_renderer_activate
; 
1263     cell_class
->start_editing 
= gtk_wx_cell_renderer_start_editing
; 
1267 gtk_wx_cell_renderer_finalize (GObject 
*object
) 
1270     (* G_OBJECT_CLASS (cell_parent_class
)->finalize
) (object
); 
1274 gtk_wx_cell_renderer_new (void) 
1276     return (GtkCellRenderer
*) g_object_new (GTK_TYPE_WX_CELL_RENDERER
, NULL
); 
1279 static GtkCellEditable 
*gtk_wx_cell_renderer_start_editing( 
1280                         GtkCellRenderer         
*renderer
, 
1281                         GdkEvent                
*WXUNUSED(event
), 
1284                         GdkRectangle            
*WXUNUSED(background_area
), 
1285                         GdkRectangle            
*cell_area
, 
1286                         GtkCellRendererState     
WXUNUSED(flags
) ) 
1288     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
1289     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
1291     // Renderer doesn't support in-place editing 
1292     if (!cell
->HasEditorCtrl()) 
1295     // An in-place editing control is still around 
1296     if (cell
->GetEditorCtrl()) 
1300     gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
, 
1306     rect
.x 
+= cell_area
->x
; 
1307     rect
.y 
+= cell_area
->y
; 
1308 //    rect.width  -= renderer->xpad * 2; 
1309 //    rect.height -= renderer->ypad * 2; 
1311 //    wxRect renderrect(wxRectFromGDKRect(&rect)); 
1312     wxRect 
renderrect(wxRectFromGDKRect(cell_area
)); 
1315         item(cell
->GetOwner()->GetOwner()->GTKPathToItem(wxGtkTreePath(path
))); 
1317     cell
->StartEditing( item
, renderrect 
); 
1323 gtk_wx_cell_renderer_get_size (GtkCellRenderer 
*renderer
, 
1324                                GtkWidget       
*WXUNUSED(widget
), 
1325                                GdkRectangle    
*cell_area
, 
1331     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
1332     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
1334     wxSize size 
= cell
->GetSize(); 
1336     gint calc_width  
= (gint
) renderer
->xpad 
* 2 + size
.x
; 
1337     gint calc_height 
= (gint
) renderer
->ypad 
* 2 + size
.y
; 
1344     if (cell_area 
&& size
.x 
> 0 && size
.y 
> 0) 
1348             *x_offset 
= (gint
)((renderer
->xalign 
* 
1349                                (cell_area
->width 
- calc_width 
- 2 * renderer
->xpad
))); 
1350             *x_offset 
= MAX (*x_offset
, 0) + renderer
->xpad
; 
1354             *y_offset 
= (gint
)((renderer
->yalign 
* 
1355                                (cell_area
->height 
- calc_height 
- 2 * renderer
->ypad
))); 
1356             *y_offset 
= MAX (*y_offset
, 0) + renderer
->ypad
; 
1361         *width 
= calc_width
; 
1364         *height 
= calc_height
; 
1368 gtk_wx_cell_renderer_render (GtkCellRenderer      
*renderer
, 
1371                              GdkRectangle         
*background_area
, 
1372                              GdkRectangle         
*cell_area
, 
1373                              GdkRectangle         
*expose_area
, 
1374                              GtkCellRendererState  flags
) 
1377     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
1378     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
1380     cell
->GTKStashRenderParams(window
, widget
, 
1381                                background_area
, expose_area
, flags
); 
1383     wxRect 
rect(wxRectFromGDKRect(cell_area
)); 
1384     rect 
= rect
.Deflate(renderer
->xpad
, renderer
->ypad
); 
1386     wxWindowDC
* dc 
= (wxWindowDC
*) cell
->GetDC(); 
1387     wxWindowDCImpl 
*impl 
= (wxWindowDCImpl 
*) dc
->GetImpl(); 
1389     // Reinitialize wxWindowDC's GDK window if drawing occurs into a different 
1390     // window such as a DnD drop window. 
1391     if (window 
!= impl
->m_gdkwindow
) 
1394         impl
->m_gdkwindow 
= window
; 
1399     if (flags 
& GTK_CELL_RENDERER_SELECTED
) 
1400         state 
|= wxDATAVIEW_CELL_SELECTED
; 
1401     if (flags 
& GTK_CELL_RENDERER_PRELIT
) 
1402         state 
|= wxDATAVIEW_CELL_PRELIT
; 
1403     if (flags 
& GTK_CELL_RENDERER_INSENSITIVE
) 
1404         state 
|= wxDATAVIEW_CELL_INSENSITIVE
; 
1405     if (flags 
& GTK_CELL_RENDERER_INSENSITIVE
) 
1406         state 
|= wxDATAVIEW_CELL_INSENSITIVE
; 
1407     if (flags 
& GTK_CELL_RENDERER_FOCUSED
) 
1408         state 
|= wxDATAVIEW_CELL_FOCUSED
; 
1409     cell
->WXCallRender( rect
, dc
, state 
); 
1413 gtk_wx_cell_renderer_activate( 
1414                         GtkCellRenderer         
*renderer
, 
1418                         GdkRectangle            
*WXUNUSED(background_area
), 
1419                         GdkRectangle            
*cell_area
, 
1420                         GtkCellRendererState     
WXUNUSED(flags
) ) 
1422     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
1423     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
1426     gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
, 
1432     rect
.x 
+= cell_area
->x
; 
1433     rect
.y 
+= cell_area
->y
; 
1434     rect
.width  
-= renderer
->xpad 
* 2; 
1435     rect
.height 
-= renderer
->ypad 
* 2; 
1437     wxRect 
renderrect(wxRectFromGDKRect(&rect
)); 
1439     wxDataViewCtrl 
* const ctrl 
= cell
->GetOwner()->GetOwner(); 
1440     wxDataViewModel 
*model 
= ctrl
->GetModel(); 
1442     wxDataViewItem 
item(ctrl
->GTKPathToItem(wxGtkTreePath(path
))); 
1444     unsigned int model_col 
= cell
->GetOwner()->GetModelColumn(); 
1450         // activated by <ENTER> 
1451         if (cell
->Activate( renderrect
, model
, item
, model_col 
)) 
1456     else if (event
->type 
== GDK_BUTTON_PRESS
) 
1458         GdkEventButton 
*button_event 
= (GdkEventButton
*) event
; 
1459         wxPoint 
pt( ((int) button_event
->x
) - renderrect
.x
, 
1460                     ((int) button_event
->y
) - renderrect
.y 
); 
1463         if (button_event
->button 
== 1) 
1465             if (cell
->LeftClick( pt
, renderrect
, model
, item
, model_col 
)) 
1467             // TODO: query system double-click time 
1468             if (button_event
->time 
- wxrenderer
->last_click 
< 400) 
1469                 if (cell
->Activate( renderrect
, model
, item
, model_col 
)) 
1472         wxrenderer
->last_click 
= button_event
->time
; 
1480 // --------------------------------------------------------- 
1481 // wxGtkDataViewModelNotifier 
1482 // --------------------------------------------------------- 
1484 class wxGtkDataViewModelNotifier
: public wxDataViewModelNotifier
 
1487     wxGtkDataViewModelNotifier( wxDataViewModel 
*wx_model
, wxDataViewCtrlInternal 
*internal 
); 
1488     ~wxGtkDataViewModelNotifier(); 
1490     virtual bool ItemAdded( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
); 
1491     virtual bool ItemDeleted( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
); 
1492     virtual bool ItemChanged( const wxDataViewItem 
&item 
); 
1493     virtual bool ValueChanged( const wxDataViewItem 
&item
, unsigned int col 
); 
1494     virtual bool Cleared(); 
1495     virtual void Resort(); 
1496     virtual bool BeforeReset(); 
1497     virtual bool AfterReset(); 
1499     void UpdateLastCount(); 
1502     wxDataViewModel         
*m_wx_model
; 
1503     wxDataViewCtrlInternal  
*m_internal
; 
1506 // --------------------------------------------------------- 
1507 // wxGtkDataViewListModelNotifier 
1508 // --------------------------------------------------------- 
1510 wxGtkDataViewModelNotifier::wxGtkDataViewModelNotifier( 
1511     wxDataViewModel 
*wx_model
, wxDataViewCtrlInternal 
*internal 
) 
1513     m_wx_model 
= wx_model
; 
1514     m_internal 
= internal
; 
1517 wxGtkDataViewModelNotifier::~wxGtkDataViewModelNotifier() 
1523 bool wxGtkDataViewModelNotifier::ItemAdded( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
) 
1525     m_internal
->ItemAdded( parent
, item 
); 
1526     GtkWxTreeModel 
*wxgtk_model 
= m_internal
->GetGtkModel(); 
1529     iter
.stamp 
= wxgtk_model
->stamp
; 
1530     iter
.user_data 
= item
.GetID(); 
1532     wxGtkTreePath 
path(wxgtk_tree_model_get_path( 
1533         GTK_TREE_MODEL(wxgtk_model
), &iter 
)); 
1534     gtk_tree_model_row_inserted( 
1535         GTK_TREE_MODEL(wxgtk_model
), path
, &iter
); 
1540 bool wxGtkDataViewModelNotifier::ItemDeleted( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
) 
1542     GtkWxTreeModel 
*wxgtk_model 
= m_internal
->GetGtkModel(); 
1544     // using _get_path for a deleted item cannot be 
1547     iter
.stamp 
= wxgtk_model
->stamp
; 
1548     iter
.user_data 
= (gpointer
) item
.GetID(); 
1549     wxGtkTreePath 
path(wxgtk_tree_model_get_path( 
1550         GTK_TREE_MODEL(wxgtk_model
), &iter 
)); 
1552     // so get the path from the parent 
1554     iter
.stamp 
= wxgtk_model
->stamp
; 
1555     iter
.user_data 
= (gpointer
) parent
.GetID(); 
1556     wxGtkTreePath 
path(wxgtk_tree_model_get_path( 
1557         GTK_TREE_MODEL(wxgtk_model
), &iter 
)); 
1558     // and add the final index ourselves 
1559     int index 
= m_internal
->GetIndexOf( parent
, item 
); 
1560     gtk_tree_path_append_index( path
, index 
); 
1563     gtk_tree_model_row_deleted( 
1564         GTK_TREE_MODEL(wxgtk_model
), path 
); 
1566     m_internal
->ItemDeleted( parent
, item 
); 
1571 void wxGtkDataViewModelNotifier::Resort() 
1573     m_internal
->Resort(); 
1576 bool wxGtkDataViewModelNotifier::ItemChanged( const wxDataViewItem 
&item 
) 
1578     GtkWxTreeModel 
*wxgtk_model 
= m_internal
->GetGtkModel(); 
1581     iter
.stamp 
= wxgtk_model
->stamp
; 
1582     iter
.user_data 
= (gpointer
) item
.GetID(); 
1584     wxGtkTreePath 
path(wxgtk_tree_model_get_path( 
1585         GTK_TREE_MODEL(wxgtk_model
), &iter 
)); 
1586     gtk_tree_model_row_changed( 
1587         GTK_TREE_MODEL(wxgtk_model
), path
, &iter 
); 
1589     m_internal
->ItemChanged( item 
); 
1594 bool wxGtkDataViewModelNotifier::ValueChanged( const wxDataViewItem 
&item
, unsigned int model_col 
) 
1596     GtkWxTreeModel 
*wxgtk_model 
= m_internal
->GetGtkModel(); 
1597     wxDataViewCtrl 
*ctrl 
= m_internal
->GetOwner(); 
1599     // This adds GTK+'s missing MVC logic for ValueChanged 
1601     for (index 
= 0; index 
< ctrl
->GetColumnCount(); index
++) 
1603         wxDataViewColumn 
*column 
= ctrl
->GetColumn( index 
); 
1604         if (column
->GetModelColumn() == model_col
) 
1606             GtkTreeView 
*widget 
= GTK_TREE_VIEW(ctrl
->GtkGetTreeView()); 
1607             GtkTreeViewColumn 
*gcolumn 
= GTK_TREE_VIEW_COLUMN(column
->GetGtkHandle()); 
1611             iter
.stamp 
= wxgtk_model
->stamp
; 
1612             iter
.user_data 
= (gpointer
) item
.GetID(); 
1613             wxGtkTreePath 
path(wxgtk_tree_model_get_path( 
1614                 GTK_TREE_MODEL(wxgtk_model
), &iter 
)); 
1615             GdkRectangle cell_area
; 
1616             gtk_tree_view_get_cell_area( widget
, path
, gcolumn
, &cell_area 
); 
1618             GtkAdjustment
* hadjust 
= gtk_tree_view_get_hadjustment( widget 
); 
1619             double d 
= gtk_adjustment_get_value( hadjust 
); 
1620             int xdiff 
= (int) d
; 
1622             int ydiff 
= gcolumn
->button
->allocation
.height
; 
1624             gtk_widget_queue_draw_area( GTK_WIDGET(widget
), 
1625                 cell_area
.x 
- xdiff
, ydiff 
+ cell_area
.y
, cell_area
.width
, cell_area
.height 
); 
1627             m_internal
->ValueChanged( item
, model_col 
); 
1636 bool wxGtkDataViewModelNotifier::BeforeReset() 
1638     GtkWidget 
*treeview 
= m_internal
->GetOwner()->GtkGetTreeView(); 
1639     gtk_tree_view_set_model( GTK_TREE_VIEW(treeview
), NULL 
); 
1644 bool wxGtkDataViewModelNotifier::AfterReset() 
1646     GtkWidget 
*treeview 
= m_internal
->GetOwner()->GtkGetTreeView(); 
1647     GtkWxTreeModel 
*wxgtk_model 
= m_internal
->GetGtkModel(); 
1649     m_internal
->Cleared();  
1651     gtk_tree_view_set_model( GTK_TREE_VIEW(treeview
), GTK_TREE_MODEL(wxgtk_model
) ); 
1656 bool wxGtkDataViewModelNotifier::Cleared() 
1658     GtkWxTreeModel 
*wxgtk_model 
= m_internal
->GetGtkModel(); 
1660     // There is no call to tell the model that everything 
1661     // has been deleted so call row_deleted() for every 
1664     int count 
= m_internal
->iter_n_children( NULL 
); // number of children of root 
1666     GtkTreePath 
*path 
= gtk_tree_path_new_first();  // points to root 
1669     for (i 
= 0; i 
< count
; i
++) 
1670         gtk_tree_model_row_deleted( GTK_TREE_MODEL(wxgtk_model
), path 
); 
1672     gtk_tree_path_free( path 
); 
1674     m_internal
->Cleared(); 
1679 // --------------------------------------------------------- 
1680 // wxDataViewRenderer 
1681 // --------------------------------------------------------- 
1683 static gpointer s_user_data 
= NULL
; 
1686 wxgtk_cell_editable_editing_done( GtkCellEditable 
*WXUNUSED(editable
), 
1687                                   wxDataViewRenderer 
*wxrenderer 
) 
1689     wxDataViewColumn 
*column 
= wxrenderer
->GetOwner(); 
1690     wxDataViewCtrl 
*dv 
= column
->GetOwner(); 
1691     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_DONE
, dv
->GetId() ); 
1692     event
.SetDataViewColumn( column 
); 
1693     event
.SetModel( dv
->GetModel() ); 
1694     wxDataViewItem 
item( s_user_data 
); 
1695     event
.SetItem( item 
); 
1696     dv
->HandleWindowEvent( event 
); 
1700 wxgtk_renderer_editing_started( GtkCellRenderer 
*WXUNUSED(cell
), GtkCellEditable 
*editable
, 
1701                                 gchar 
*path
, wxDataViewRenderer 
*wxrenderer 
) 
1706     wxDataViewColumn 
*column 
= wxrenderer
->GetOwner(); 
1707     wxDataViewCtrl 
*dv 
= column
->GetOwner(); 
1708     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_STARTED
, dv
->GetId() ); 
1709     event
.SetDataViewColumn( column 
); 
1710     event
.SetModel( dv
->GetModel() ); 
1711     wxDataViewItem 
item(dv
->GTKPathToItem(wxGtkTreePath(path
))); 
1712     event
.SetItem( item 
); 
1713     dv
->HandleWindowEvent( event 
); 
1715     if (GTK_IS_CELL_EDITABLE(editable
)) 
1717         s_user_data 
= item
.GetID(); 
1719         g_signal_connect (GTK_CELL_EDITABLE (editable
), "editing_done", 
1720             G_CALLBACK (wxgtk_cell_editable_editing_done
), 
1721             (gpointer
) wxrenderer 
); 
1727 IMPLEMENT_ABSTRACT_CLASS(wxDataViewRenderer
, wxDataViewRendererBase
) 
1729 wxDataViewRenderer::wxDataViewRenderer( const wxString 
&varianttype
, wxDataViewCellMode mode
, 
1731     wxDataViewRendererBase( varianttype
, mode
, align 
) 
1735     // we haven't changed them yet 
1736     m_usingDefaultAttrs 
= true; 
1738     // NOTE: SetMode() and SetAlignment() needs to be called in the renderer's ctor, 
1739     //       after the m_renderer pointer has been initialized 
1742 void wxDataViewRenderer::GtkPackIntoColumn(GtkTreeViewColumn 
*column
) 
1744     gtk_tree_view_column_pack_end( column
, m_renderer
, TRUE 
/* expand */); 
1747 void wxDataViewRenderer::GtkInitHandlers() 
1749     if (!gtk_check_version(2,6,0)) 
1751         g_signal_connect (GTK_CELL_RENDERER(m_renderer
), "editing_started", 
1752             G_CALLBACK (wxgtk_renderer_editing_started
), 
1757 void wxDataViewRenderer::SetMode( wxDataViewCellMode mode 
) 
1759     GtkCellRendererMode gtkMode
; 
1762         case wxDATAVIEW_CELL_INERT
: 
1763             gtkMode 
= GTK_CELL_RENDERER_MODE_INERT
; 
1766         case wxDATAVIEW_CELL_ACTIVATABLE
: 
1767             gtkMode 
= GTK_CELL_RENDERER_MODE_ACTIVATABLE
; 
1770         case wxDATAVIEW_CELL_EDITABLE
: 
1771             gtkMode 
= GTK_CELL_RENDERER_MODE_EDITABLE
; 
1775             wxFAIL_MSG( "unknown wxDataViewCellMode value" ); 
1779     // This value is most often ignored in GtkTreeView 
1780     GValue gvalue 
= { 0, }; 
1781     g_value_init( &gvalue
, gtk_cell_renderer_mode_get_type() ); 
1782     g_value_set_enum( &gvalue
, gtkMode 
); 
1783     g_object_set_property( G_OBJECT(m_renderer
), "mode", &gvalue 
); 
1784     g_value_unset( &gvalue 
); 
1787 wxDataViewCellMode 
wxDataViewRenderer::GetMode() const 
1789     wxDataViewCellMode ret
; 
1792     g_object_get( G_OBJECT(m_renderer
), "mode", &gvalue
, NULL
); 
1794     switch (g_value_get_enum(&gvalue
)) 
1797             wxFAIL_MSG( "unknown GtkCellRendererMode value" ); 
1798             // fall through (we have to return something) 
1800         case GTK_CELL_RENDERER_MODE_INERT
: 
1801             ret 
= wxDATAVIEW_CELL_INERT
; 
1804         case GTK_CELL_RENDERER_MODE_ACTIVATABLE
: 
1805             ret 
= wxDATAVIEW_CELL_ACTIVATABLE
; 
1808         case GTK_CELL_RENDERER_MODE_EDITABLE
: 
1809             ret 
= wxDATAVIEW_CELL_EDITABLE
; 
1813     g_value_unset( &gvalue 
); 
1818 void wxDataViewRenderer::GtkUpdateAlignment() 
1820     int align 
= m_alignment
; 
1822     // query alignment from column ? 
1826         if (GetOwner() == NULL
) 
1829         align 
= GetOwner()->GetAlignment(); 
1830         align 
|= wxALIGN_CENTRE_VERTICAL
; 
1833     // horizontal alignment: 
1835     gfloat xalign 
= 0.0; 
1836     if (align 
& wxALIGN_RIGHT
) 
1838     else if (align 
& wxALIGN_CENTER_HORIZONTAL
) 
1841     GValue gvalue 
= { 0, }; 
1842     g_value_init( &gvalue
, G_TYPE_FLOAT 
); 
1843     g_value_set_float( &gvalue
, xalign 
); 
1844     g_object_set_property( G_OBJECT(m_renderer
), "xalign", &gvalue 
); 
1845     g_value_unset( &gvalue 
); 
1847     // vertical alignment: 
1849     gfloat yalign 
= 0.0; 
1850     if (align 
& wxALIGN_BOTTOM
) 
1852     else if (align 
& wxALIGN_CENTER_VERTICAL
) 
1855     GValue gvalue2 
= { 0, }; 
1856     g_value_init( &gvalue2
, G_TYPE_FLOAT 
); 
1857     g_value_set_float( &gvalue2
, yalign 
); 
1858     g_object_set_property( G_OBJECT(m_renderer
), "yalign", &gvalue2 
); 
1859     g_value_unset( &gvalue2 
); 
1862 void wxDataViewRenderer::SetAlignment( int align 
) 
1864     m_alignment 
= align
; 
1865     GtkUpdateAlignment(); 
1868 int wxDataViewRenderer::GetAlignment() const 
1873 void wxDataViewRenderer::EnableEllipsize(wxEllipsizeMode mode
) 
1876     if ( gtk_check_version(2, 6, 0) != NULL 
) 
1879     GtkCellRendererText 
* const rend 
= GtkGetTextRenderer(); 
1883     // we use the same values in wxEllipsizeMode as PangoEllipsizeMode so we 
1884     // can just cast between them 
1885     GValue gvalue 
= { 0, }; 
1886     g_value_init( &gvalue
, PANGO_TYPE_ELLIPSIZE_MODE 
); 
1887     g_value_set_enum( &gvalue
, static_cast<PangoEllipsizeMode
>(mode
) ); 
1888     g_object_set_property( G_OBJECT(rend
), "ellipsize", &gvalue 
); 
1889     g_value_unset( &gvalue 
); 
1892 #endif // GTK 2.6/before 
1895 wxEllipsizeMode 
wxDataViewRenderer::GetEllipsizeMode() const 
1898     if ( gtk_check_version(2, 6, 0) != NULL 
) 
1899         return wxELLIPSIZE_NONE
; 
1901     GtkCellRendererText 
* const rend 
= GtkGetTextRenderer(); 
1903         return wxELLIPSIZE_NONE
; 
1905     GValue gvalue 
= { 0, }; 
1906     g_value_init( &gvalue
, PANGO_TYPE_ELLIPSIZE_MODE 
); 
1907     g_object_get_property( G_OBJECT(rend
), "ellipsize", &gvalue 
); 
1909         mode 
= static_cast<wxEllipsizeMode
>(g_value_get_enum( &gvalue 
)); 
1910     g_value_unset( &gvalue 
); 
1914     return wxELLIPSIZE_NONE
; 
1915 #endif // GTK 2.6/before 
1919 wxDataViewRenderer::GtkOnTextEdited(const gchar 
*itempath
, const wxString
& str
) 
1921     wxVariant 
value(str
); 
1922     if (!Validate( value 
)) 
1926         item(GetOwner()->GetOwner()->GTKPathToItem(wxGtkTreePath(itempath
))); 
1928     GtkOnCellChanged(value
, item
, GetOwner()->GetModelColumn()); 
1932 wxDataViewRenderer::GtkOnCellChanged(const wxVariant
& value
, 
1933                                      const wxDataViewItem
& item
, 
1936     wxDataViewModel 
*model 
= GetOwner()->GetOwner()->GetModel(); 
1937     model
->ChangeValue( value
, item
, col 
); 
1940 // --------------------------------------------------------- 
1941 // wxDataViewTextRenderer 
1942 // --------------------------------------------------------- 
1947 static void wxGtkTextRendererEditedCallback( GtkCellRendererText 
*WXUNUSED(renderer
), 
1948     gchar 
*arg1
, gchar 
*arg2
, gpointer user_data 
) 
1950     wxDataViewRenderer 
*cell 
= (wxDataViewRenderer
*) user_data
; 
1952     cell
->GtkOnTextEdited(arg1
, wxGTK_CONV_BACK_FONT( 
1953                 arg2
, cell
->GetOwner()->GetOwner()->GetFont())); 
1961 // helper function used by wxDataViewTextRenderer and 
1962 // wxDataViewCustomRenderer::RenderText(): it applies the attributes to the 
1963 // given text renderer and returns true if anything was done 
1964 bool GtkApplyAttr(GtkCellRendererText 
*renderer
, const wxDataViewItemAttr
& attr
) 
1966     bool usingDefaultAttrs 
= true; 
1967     if (attr
.HasColour()) 
1969         const GdkColor 
* const gcol 
= attr
.GetColour().GetColor(); 
1971         GValue gvalue 
= { 0, }; 
1972         g_value_init( &gvalue
, GDK_TYPE_COLOR 
); 
1973         g_value_set_boxed( &gvalue
, gcol 
); 
1974         g_object_set_property( G_OBJECT(renderer
), "foreground_gdk", &gvalue 
); 
1975         g_value_unset( &gvalue 
); 
1977         usingDefaultAttrs 
= false; 
1981         GValue gvalue 
= { 0, }; 
1982         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1983         g_value_set_boolean( &gvalue
, FALSE 
); 
1984         g_object_set_property( G_OBJECT(renderer
), "foreground-set", &gvalue 
); 
1985         g_value_unset( &gvalue 
); 
1988     if (attr
.GetItalic()) 
1990         GValue gvalue 
= { 0, }; 
1991         g_value_init( &gvalue
, PANGO_TYPE_STYLE 
); 
1992         g_value_set_enum( &gvalue
, PANGO_STYLE_ITALIC 
); 
1993         g_object_set_property( G_OBJECT(renderer
), "style", &gvalue 
); 
1994         g_value_unset( &gvalue 
); 
1996         usingDefaultAttrs 
= false; 
2000         GValue gvalue 
= { 0, }; 
2001         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
2002         g_value_set_boolean( &gvalue
, FALSE 
); 
2003         g_object_set_property( G_OBJECT(renderer
), "style-set", &gvalue 
); 
2004         g_value_unset( &gvalue 
); 
2010         GValue gvalue 
= { 0, }; 
2011         g_value_init( &gvalue
, PANGO_TYPE_WEIGHT 
); 
2012         g_value_set_enum( &gvalue
, PANGO_WEIGHT_BOLD 
); 
2013         g_object_set_property( G_OBJECT(renderer
), "weight", &gvalue 
); 
2014         g_value_unset( &gvalue 
); 
2016         usingDefaultAttrs 
= false; 
2020         GValue gvalue 
= { 0, }; 
2021         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
2022         g_value_set_boolean( &gvalue
, FALSE 
); 
2023         g_object_set_property( G_OBJECT(renderer
), "weight-set", &gvalue 
); 
2024         g_value_unset( &gvalue 
); 
2028     if (attr
.HasBackgroundColour()) 
2030         wxColour colour 
= attr
.GetBackgroundColour(); 
2031         const GdkColor 
* const gcol 
= colour
.GetColor(); 
2033         GValue gvalue 
= { 0, }; 
2034         g_value_init( &gvalue
, GDK_TYPE_COLOR 
); 
2035         g_value_set_boxed( &gvalue
, gcol 
); 
2036         g_object_set_property( G_OBJECT(renderer
), "cell-background_gdk", &gvalue 
); 
2037         g_value_unset( &gvalue 
); 
2041         GValue gvalue 
= { 0, }; 
2042         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
2043         g_value_set_boolean( &gvalue
, FALSE 
); 
2044         g_object_set_property( G_OBJECT(renderer
), "cell-background-set", &gvalue 
); 
2045         g_value_unset( &gvalue 
); 
2049     return !usingDefaultAttrs
; 
2052 } // anonymous namespace 
2054 IMPLEMENT_CLASS(wxDataViewTextRenderer
, wxDataViewRenderer
) 
2056 wxDataViewTextRenderer::wxDataViewTextRenderer( const wxString 
&varianttype
, wxDataViewCellMode mode
, 
2058     wxDataViewRenderer( varianttype
, mode
, align 
) 
2060     GtkWxCellRendererText 
*text_renderer 
= gtk_wx_cell_renderer_text_new(); 
2061     text_renderer
->wx_renderer 
= this; 
2062     m_renderer 
= (GtkCellRenderer
*) text_renderer
; 
2064     if (mode 
& wxDATAVIEW_CELL_EDITABLE
) 
2066         GValue gvalue 
= { 0, }; 
2067         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
2068         g_value_set_boolean( &gvalue
, true ); 
2069         g_object_set_property( G_OBJECT(m_renderer
), "editable", &gvalue 
); 
2070         g_value_unset( &gvalue 
); 
2072         g_signal_connect_after( m_renderer
, "edited", G_CALLBACK(wxGtkTextRendererEditedCallback
), this ); 
2078     SetAlignment(align
); 
2081 bool wxDataViewTextRenderer::SetTextValue(const wxString
& str
) 
2083     GValue gvalue 
= { 0, }; 
2084     g_value_init( &gvalue
, G_TYPE_STRING 
); 
2085     g_value_set_string( &gvalue
, wxGTK_CONV_FONT( str
, GetOwner()->GetOwner()->GetFont() ) ); 
2086     g_object_set_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
2087     g_value_unset( &gvalue 
); 
2092 bool wxDataViewTextRenderer::GetTextValue(wxString
& str
) const 
2094     GValue gvalue 
= { 0, }; 
2095     g_value_init( &gvalue
, G_TYPE_STRING 
); 
2096     g_object_get_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
2097     str 
= wxGTK_CONV_BACK_FONT( g_value_get_string( &gvalue 
), const_cast<wxDataViewTextRenderer
*>(this)->GetOwner()->GetOwner()->GetFont() ); 
2098     g_value_unset( &gvalue 
); 
2103 void wxDataViewTextRenderer::SetAlignment( int align 
) 
2105     wxDataViewRenderer::SetAlignment(align
); 
2107     if (gtk_check_version(2,10,0)) 
2110     // horizontal alignment: 
2111     PangoAlignment pangoAlign 
= PANGO_ALIGN_LEFT
; 
2112     if (align 
& wxALIGN_RIGHT
) 
2113         pangoAlign 
= PANGO_ALIGN_RIGHT
; 
2114     else if (align 
& wxALIGN_CENTER_HORIZONTAL
) 
2115         pangoAlign 
= PANGO_ALIGN_CENTER
; 
2117     GValue gvalue 
= { 0, }; 
2118     g_value_init( &gvalue
, gtk_cell_renderer_mode_get_type() ); 
2119     g_value_set_enum( &gvalue
, pangoAlign 
); 
2120     g_object_set_property( G_OBJECT(m_renderer
), "alignment", &gvalue 
); 
2121     g_value_unset( &gvalue 
); 
2124 bool wxDataViewTextRenderer::GtkSetAttr(const wxDataViewItemAttr
& attr
) 
2126     return GtkApplyAttr(GtkGetTextRenderer(), attr
); 
2129 GtkCellRendererText 
*wxDataViewTextRenderer::GtkGetTextRenderer() const 
2131     return GTK_CELL_RENDERER_TEXT(m_renderer
); 
2134 // --------------------------------------------------------- 
2135 // wxDataViewBitmapRenderer 
2136 // --------------------------------------------------------- 
2141 // set "pixbuf" property on the given renderer 
2142 void SetPixbufProp(GtkCellRenderer 
*renderer
, GdkPixbuf 
*pixbuf
) 
2144     GValue gvalue 
= { 0, }; 
2145     g_value_init( &gvalue
, G_TYPE_OBJECT 
); 
2146     g_value_set_object( &gvalue
, pixbuf 
); 
2147     g_object_set_property( G_OBJECT(renderer
), "pixbuf", &gvalue 
); 
2148     g_value_unset( &gvalue 
); 
2151 } // anonymous namespace 
2153 IMPLEMENT_CLASS(wxDataViewBitmapRenderer
, wxDataViewRenderer
) 
2155 wxDataViewBitmapRenderer::wxDataViewBitmapRenderer( const wxString 
&varianttype
, wxDataViewCellMode mode
, 
2157     wxDataViewRenderer( varianttype
, mode
, align 
) 
2159     m_renderer 
= gtk_cell_renderer_pixbuf_new(); 
2162     SetAlignment(align
); 
2165 bool wxDataViewBitmapRenderer::SetValue( const wxVariant 
&value 
) 
2167     if (value
.GetType() == wxT("wxBitmap")) 
2172         // GetPixbuf() may create a Pixbuf representation in the wxBitmap 
2173         // object (and it will stay there and remain owned by wxBitmap) 
2174         SetPixbufProp(m_renderer
, bitmap
.GetPixbuf()); 
2176     else if (value
.GetType() == wxT("wxIcon")) 
2181         SetPixbufProp(m_renderer
, icon
.GetPixbuf()); 
2191 bool wxDataViewBitmapRenderer::GetValue( wxVariant 
&WXUNUSED(value
) ) const 
2196 // --------------------------------------------------------- 
2197 // wxDataViewToggleRenderer 
2198 // --------------------------------------------------------- 
2201 static void wxGtkToggleRendererToggledCallback( GtkCellRendererToggle 
*renderer
, 
2202     gchar 
*path
, gpointer user_data 
); 
2205 static void wxGtkToggleRendererToggledCallback( GtkCellRendererToggle 
*renderer
, 
2206     gchar 
*path
, gpointer user_data 
) 
2208     wxDataViewToggleRenderer 
*cell 
= (wxDataViewToggleRenderer
*) user_data
; 
2211     GValue gvalue 
= { 0, }; 
2212     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
2213     g_object_get_property( G_OBJECT(renderer
), "active", &gvalue 
); 
2214     bool tmp 
= g_value_get_boolean( &gvalue 
); 
2215     g_value_unset( &gvalue 
); 
2219     wxVariant value 
= tmp
; 
2220     if (!cell
->Validate( value 
)) 
2223     wxDataViewCtrl 
* const ctrl 
= cell
->GetOwner()->GetOwner(); 
2224     wxDataViewModel 
*model 
= ctrl
->GetModel(); 
2226     wxDataViewItem 
item(ctrl
->GTKPathToItem(wxGtkTreePath(path
))); 
2228     unsigned int model_col 
= cell
->GetOwner()->GetModelColumn(); 
2230     model
->ChangeValue( value
, item
, model_col 
); 
2233 IMPLEMENT_CLASS(wxDataViewToggleRenderer
, wxDataViewRenderer
) 
2235 wxDataViewToggleRenderer::wxDataViewToggleRenderer( const wxString 
&varianttype
, 
2236                                                     wxDataViewCellMode mode
, int align 
) : 
2237     wxDataViewRenderer( varianttype
, mode
, align 
) 
2239     m_renderer 
= (GtkCellRenderer
*) gtk_cell_renderer_toggle_new(); 
2241     if (mode 
& wxDATAVIEW_CELL_ACTIVATABLE
) 
2243         g_signal_connect_after( m_renderer
, "toggled", 
2244                                 G_CALLBACK(wxGtkToggleRendererToggledCallback
), this ); 
2248         GValue gvalue 
= { 0, }; 
2249         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
2250         g_value_set_boolean( &gvalue
, false ); 
2251         g_object_set_property( G_OBJECT(m_renderer
), "activatable", &gvalue 
); 
2252         g_value_unset( &gvalue 
); 
2256     SetAlignment(align
); 
2259 bool wxDataViewToggleRenderer::SetValue( const wxVariant 
&value 
) 
2263     GValue gvalue 
= { 0, }; 
2264     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
2265     g_value_set_boolean( &gvalue
, tmp 
); 
2266     g_object_set_property( G_OBJECT(m_renderer
), "active", &gvalue 
); 
2267     g_value_unset( &gvalue 
); 
2272 bool wxDataViewToggleRenderer::GetValue( wxVariant 
&value 
) const 
2274     GValue gvalue 
= { 0, }; 
2275     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
2276     g_object_get_property( G_OBJECT(m_renderer
), "active", &gvalue 
); 
2277     bool tmp 
= g_value_get_boolean( &gvalue 
); 
2278     g_value_unset( &gvalue 
); 
2285 // --------------------------------------------------------- 
2286 // wxDataViewCustomRenderer 
2287 // --------------------------------------------------------- 
2289 class wxDataViewCtrlDCImpl
: public wxWindowDCImpl
 
2292    wxDataViewCtrlDCImpl( wxDC 
*owner
, wxDataViewCtrl 
*window 
) : 
2293        wxWindowDCImpl( owner 
) 
2295         GtkWidget 
*widget 
= window
->m_treeview
; 
2301         m_context 
= window
->GTKGetPangoDefaultContext(); 
2302         m_layout 
= pango_layout_new( m_context 
); 
2303         m_fontdesc 
= pango_font_description_copy( widget
->style
->font_desc 
); 
2305         m_cmap 
= gtk_widget_get_colormap( widget 
? widget 
: window
->m_widget 
); 
2307         // Set m_gdkwindow later 
2312 class wxDataViewCtrlDC
: public wxWindowDC
 
2315     wxDataViewCtrlDC( wxDataViewCtrl 
*window 
) : 
2316         wxWindowDC( new wxDataViewCtrlDCImpl( this, window 
) ) 
2321 // --------------------------------------------------------- 
2322 // wxDataViewCustomRenderer 
2323 // --------------------------------------------------------- 
2325 IMPLEMENT_CLASS(wxDataViewCustomRenderer
, wxDataViewRenderer
) 
2327 wxDataViewCustomRenderer::wxDataViewCustomRenderer( const wxString 
&varianttype
, 
2328                                                     wxDataViewCellMode mode
, 
2331     : wxDataViewCustomRendererBase( varianttype
, mode
, align 
) 
2334     m_text_renderer 
= NULL
; 
2342 GtkCellRendererText 
*wxDataViewCustomRenderer::GtkGetTextRenderer() const 
2344     if ( !m_text_renderer 
) 
2346         // we create it on demand so need to do it even from a const function 
2347         const_cast<wxDataViewCustomRenderer 
*>(this)-> 
2348         m_text_renderer 
= GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new()); 
2351     return m_text_renderer
; 
2354 void wxDataViewCustomRenderer::RenderText( const wxString 
&text
, 
2358                                            int WXUNUSED(state
) ) 
2361     GtkCellRendererText 
* const textRenderer 
= GtkGetTextRenderer(); 
2363     GValue gvalue 
= { 0, }; 
2364     g_value_init( &gvalue
, G_TYPE_STRING 
); 
2365     g_value_set_string( &gvalue
, wxGTK_CONV_FONT( text
, GetOwner()->GetOwner()->GetFont() ) ); 
2366     g_object_set_property( G_OBJECT(textRenderer
), "text", &gvalue 
); 
2367     g_value_unset( &gvalue 
); 
2369     GtkApplyAttr(textRenderer
, GetAttr()); 
2371     GdkRectangle cell_area
; 
2372     wxRectToGDKRect(cell
, cell_area
); 
2373     cell_area
.x 
+= xoffset
; 
2374     cell_area
.width 
-= xoffset
; 
2376     gtk_cell_renderer_render( GTK_CELL_RENDERER(textRenderer
), 
2377         m_renderParams
.window
, 
2378         m_renderParams
.widget
, 
2379         m_renderParams
.background_area
, 
2381         m_renderParams
.expose_area
, 
2382         (GtkCellRendererState
) m_renderParams
.flags 
); 
2385 bool wxDataViewCustomRenderer::Init(wxDataViewCellMode mode
, int align
) 
2387     GtkWxCellRenderer 
*renderer 
= (GtkWxCellRenderer 
*) gtk_wx_cell_renderer_new(); 
2388     renderer
->cell 
= this; 
2390     m_renderer 
= (GtkCellRenderer
*) renderer
; 
2393     SetAlignment(align
); 
2400 wxDataViewCustomRenderer::~wxDataViewCustomRenderer() 
2405     if (m_text_renderer
) 
2406         gtk_object_sink( GTK_OBJECT(m_text_renderer
) ); 
2409 wxDC 
*wxDataViewCustomRenderer::GetDC() 
2413         if (GetOwner() == NULL
) 
2415         if (GetOwner()->GetOwner() == NULL
) 
2417         m_dc 
= new wxDataViewCtrlDC( GetOwner()->GetOwner() ); 
2423 // --------------------------------------------------------- 
2424 // wxDataViewProgressRenderer 
2425 // --------------------------------------------------------- 
2427 IMPLEMENT_CLASS(wxDataViewProgressRenderer
, wxDataViewCustomRenderer
) 
2429 wxDataViewProgressRenderer::wxDataViewProgressRenderer( const wxString 
&label
, 
2430     const wxString 
&varianttype
, wxDataViewCellMode mode
, int align 
) : 
2431     wxDataViewCustomRenderer( varianttype
, mode
, align
, true ) 
2437     if (!gtk_check_version(2,6,0)) 
2439         m_renderer 
= (GtkCellRenderer
*) gtk_cell_renderer_progress_new(); 
2441         GValue gvalue 
= { 0, }; 
2442         g_value_init( &gvalue
, G_TYPE_STRING 
); 
2444         g_value_set_string( &gvalue
, wxGTK_CONV_FONT( m_label
, GetOwner()->GetOwner()->GetFont() ) ); 
2445         g_object_set_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
2446         g_value_unset( &gvalue 
); 
2449         SetAlignment(align
); 
2454         // Use custom cell code 
2455         wxDataViewCustomRenderer::Init(mode
, align
); 
2459 wxDataViewProgressRenderer::~wxDataViewProgressRenderer() 
2463 bool wxDataViewProgressRenderer::SetValue( const wxVariant 
&value 
) 
2466     if (!gtk_check_version(2,6,0)) 
2468         gint tmp 
= (long) value
; 
2469         GValue gvalue 
= { 0, }; 
2470         g_value_init( &gvalue
, G_TYPE_INT 
); 
2471         g_value_set_int( &gvalue
, tmp 
); 
2472         g_object_set_property( G_OBJECT(m_renderer
), "value", &gvalue 
); 
2473         g_value_unset( &gvalue 
); 
2478         m_value 
= (long) value
; 
2480         if (m_value 
< 0) m_value 
= 0; 
2481         if (m_value 
> 100) m_value 
= 100; 
2487 bool wxDataViewProgressRenderer::GetValue( wxVariant 
&WXUNUSED(value
) ) const 
2492 bool wxDataViewProgressRenderer::Render( wxRect cell
, wxDC 
*dc
, int WXUNUSED(state
) ) 
2494     double pct 
= (double)m_value 
/ 100.0; 
2496     bar
.width 
= (int)(cell
.width 
* pct
); 
2497     dc
->SetPen( *wxTRANSPARENT_PEN 
); 
2498     dc
->SetBrush( *wxBLUE_BRUSH 
); 
2499     dc
->DrawRectangle( bar 
); 
2501     dc
->SetBrush( *wxTRANSPARENT_BRUSH 
); 
2502     dc
->SetPen( *wxBLACK_PEN 
); 
2503     dc
->DrawRectangle( cell 
); 
2508 wxSize 
wxDataViewProgressRenderer::GetSize() const 
2510     return wxSize(40,12); 
2513 // ------------------------------------- 
2514 // wxDataViewChoiceRenderer 
2515 // ------------------------------------- 
2517 wxDataViewChoiceRenderer::wxDataViewChoiceRenderer( const wxArrayString 
&choices
, 
2518                             wxDataViewCellMode mode
, int alignment  
) : 
2519     wxDataViewCustomRenderer( "string", mode
, alignment
, true ) 
2521    m_choices 
= choices
; 
2524     if (!gtk_check_version(2,6,0)) 
2526         m_renderer 
= (GtkCellRenderer
*) gtk_cell_renderer_combo_new(); 
2528         GtkListStore 
*store 
= gtk_list_store_new( 1, G_TYPE_STRING 
); 
2529         for (size_t n 
= 0; n 
< m_choices
.GetCount(); n
++) 
2531             gtk_list_store_insert_with_values( 
2533                 static_cast<const char *>(m_choices
[n
].utf8_str()), -1 ); 
2536         g_object_set (m_renderer
, 
2542         bool editable 
= (mode 
& wxDATAVIEW_CELL_EDITABLE
); 
2543         g_object_set (m_renderer
, "editable", editable
, NULL
); 
2545         SetAlignment(alignment
); 
2547         g_signal_connect_after( m_renderer
, "edited", G_CALLBACK(wxGtkTextRendererEditedCallback
), this ); 
2554         // Use custom cell code 
2555         wxDataViewCustomRenderer::Init(mode
, alignment
); 
2559 bool wxDataViewChoiceRenderer::Render( wxRect rect
, wxDC 
*dc
, int state 
) 
2561     RenderText( m_data
, 0, rect
, dc
, state 
); 
2565 wxSize 
wxDataViewChoiceRenderer::GetSize() const 
2567     return wxSize(70,20); 
2570 bool wxDataViewChoiceRenderer::SetValue( const wxVariant 
&value 
) 
2574     if (!gtk_check_version(2,6,0)) 
2576         GValue gvalue 
= { 0, }; 
2577         g_value_init( &gvalue
, G_TYPE_STRING 
); 
2578         g_value_set_string(&gvalue
, 
2579                            wxGTK_CONV_FONT(value
.GetString(), 
2580                                            GetOwner()->GetOwner()->GetFont())); 
2581         g_object_set_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
2582         g_value_unset( &gvalue 
); 
2586         m_data 
= value
.GetString(); 
2591 bool wxDataViewChoiceRenderer::GetValue( wxVariant 
&value 
) const 
2594     if (!gtk_check_version(2,6,0)) 
2596         GValue gvalue 
= { 0, }; 
2597         g_value_init( &gvalue
, G_TYPE_STRING 
); 
2598         g_object_get_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
2599         wxString temp 
= wxGTK_CONV_BACK_FONT(g_value_get_string(&gvalue
), 
2600                                              GetOwner()->GetOwner()->GetFont()); 
2601         g_value_unset( &gvalue 
); 
2604         //wxPrintf( "temp %s\n", temp ); 
2605         // TODO: remove this code 
2614 void wxDataViewChoiceRenderer::SetAlignment( int align 
) 
2616     wxDataViewCustomRenderer::SetAlignment(align
); 
2618     if (gtk_check_version(2,10,0)) 
2621     // horizontal alignment: 
2622     PangoAlignment pangoAlign 
= PANGO_ALIGN_LEFT
; 
2623     if (align 
& wxALIGN_RIGHT
) 
2624         pangoAlign 
= PANGO_ALIGN_RIGHT
; 
2625     else if (align 
& wxALIGN_CENTER_HORIZONTAL
) 
2626         pangoAlign 
= PANGO_ALIGN_CENTER
; 
2628     GValue gvalue 
= { 0, }; 
2629     g_value_init( &gvalue
, gtk_cell_renderer_mode_get_type() ); 
2630     g_value_set_enum( &gvalue
, pangoAlign 
); 
2631     g_object_set_property( G_OBJECT(m_renderer
), "alignment", &gvalue 
); 
2632     g_value_unset( &gvalue 
); 
2635 // ---------------------------------------------------------------------------- 
2636 // wxDataViewChoiceByIndexRenderer 
2637 // ---------------------------------------------------------------------------- 
2639 wxDataViewChoiceByIndexRenderer::wxDataViewChoiceByIndexRenderer( const wxArrayString 
&choices
, 
2640                               wxDataViewCellMode mode
, int alignment 
) : 
2641       wxDataViewChoiceRenderer( choices
, mode
, alignment 
) 
2645 void wxDataViewChoiceByIndexRenderer::GtkOnTextEdited(const gchar 
*itempath
, const wxString
& str
) 
2647     wxVariant 
value( (long) GetChoices().Index( str 
) ); 
2649     if (!Validate( value 
)) 
2653         item(GetOwner()->GetOwner()->GTKPathToItem(wxGtkTreePath(itempath
))); 
2655     GtkOnCellChanged(value
, item
, GetOwner()->GetModelColumn()); 
2658 bool wxDataViewChoiceByIndexRenderer::SetValue( const wxVariant 
&value 
) 
2660     wxVariant string_value 
= GetChoice( value
.GetLong() ); 
2661     return wxDataViewChoiceRenderer::SetValue( string_value 
); 
2664 bool wxDataViewChoiceByIndexRenderer::GetValue( wxVariant 
&value 
) const 
2666     wxVariant string_value
; 
2667     if (!wxDataViewChoiceRenderer::GetValue( string_value 
)) 
2670     value 
= (long) GetChoices().Index( string_value
.GetString() ); 
2674 // --------------------------------------------------------- 
2675 // wxDataViewDateRenderer 
2676 // --------------------------------------------------------- 
2678 class wxDataViewDateRendererPopupTransient
: public wxPopupTransientWindow
 
2681     wxDataViewDateRendererPopupTransient( wxWindow
* parent
, wxDateTime 
*value
, 
2682         wxDataViewModel 
*model
, const wxDataViewItem 
&item
, unsigned int col 
) : 
2683         wxPopupTransientWindow( parent
, wxBORDER_SIMPLE 
) 
2688         m_cal 
= new wxCalendarCtrl( this, -1, *value 
); 
2689         wxBoxSizer 
*sizer 
= new wxBoxSizer( wxHORIZONTAL 
); 
2690         sizer
->Add( m_cal
, 1, wxGROW 
); 
2695     virtual void OnDismiss() 
2699     void OnCalendar( wxCalendarEvent 
&event 
); 
2701     wxCalendarCtrl   
*m_cal
; 
2702     wxDataViewModel  
*m_model
; 
2703     wxDataViewItem    m_item
; 
2707     DECLARE_EVENT_TABLE() 
2710 BEGIN_EVENT_TABLE(wxDataViewDateRendererPopupTransient
,wxPopupTransientWindow
) 
2711     EVT_CALENDAR( -1, wxDataViewDateRendererPopupTransient::OnCalendar 
) 
2714 void wxDataViewDateRendererPopupTransient::OnCalendar( wxCalendarEvent 
&event 
) 
2716     m_model
->ChangeValue( event
.GetDate(), m_item
, m_col 
); 
2720 IMPLEMENT_CLASS(wxDataViewDateRenderer
, wxDataViewCustomRenderer
) 
2722 wxDataViewDateRenderer::wxDataViewDateRenderer( const wxString 
&varianttype
, 
2723                         wxDataViewCellMode mode
, int align 
) : 
2724     wxDataViewCustomRenderer( varianttype
, mode
, align 
) 
2727     SetAlignment(align
); 
2730 bool wxDataViewDateRenderer::SetValue( const wxVariant 
&value 
) 
2732     m_date 
= value
.GetDateTime(); 
2737 bool wxDataViewDateRenderer::GetValue( wxVariant 
&WXUNUSED(value
) ) const 
2742 bool wxDataViewDateRenderer::Render( wxRect cell
, wxDC 
*dc
, int state 
) 
2744     dc
->SetFont( GetOwner()->GetOwner()->GetFont() ); 
2745     wxString tmp 
= m_date
.FormatDate(); 
2746     RenderText( tmp
, 0, cell
, dc
, state 
); 
2750 wxSize 
wxDataViewDateRenderer::GetSize() const 
2752     wxString tmp 
= m_date
.FormatDate(); 
2754     GetView()->GetTextExtent( tmp
, &x
, &y
, &d 
); 
2755     return wxSize(x
,y
+d
); 
2758 bool wxDataViewDateRenderer::Activate( wxRect 
WXUNUSED(cell
), wxDataViewModel 
*model
, 
2759                                        const wxDataViewItem 
&item
, unsigned int col 
) 
2762     model
->GetValue( variant
, item
, col 
); 
2763     wxDateTime value 
= variant
.GetDateTime(); 
2765     wxDataViewDateRendererPopupTransient 
*popup 
= new wxDataViewDateRendererPopupTransient( 
2766         GetOwner()->GetOwner()->GetParent(), &value
, model
, item
, col 
); 
2767     wxPoint pos 
= wxGetMousePosition(); 
2770     popup
->Popup( popup
->m_cal 
); 
2776 // --------------------------------------------------------- 
2777 // wxDataViewIconTextRenderer 
2778 // --------------------------------------------------------- 
2780 IMPLEMENT_CLASS(wxDataViewIconTextRenderer
, wxDataViewCustomRenderer
) 
2782 wxDataViewIconTextRenderer::wxDataViewIconTextRenderer
 
2784                              const wxString 
&varianttype
, 
2785                              wxDataViewCellMode mode
, 
2788     : wxDataViewTextRenderer(varianttype
, mode
, align
) 
2790     m_rendererIcon 
= gtk_cell_renderer_pixbuf_new(); 
2793 wxDataViewIconTextRenderer::~wxDataViewIconTextRenderer() 
2797 void wxDataViewIconTextRenderer::GtkPackIntoColumn(GtkTreeViewColumn 
*column
) 
2799     // add the icon renderer first 
2800     gtk_tree_view_column_pack_start(column
, m_rendererIcon
, FALSE 
/* !expand */); 
2802     // add the text renderer too 
2803     wxDataViewRenderer::GtkPackIntoColumn(column
); 
2806 bool wxDataViewIconTextRenderer::SetValue( const wxVariant 
&value 
) 
2810     SetTextValue(m_value
.GetText()); 
2811     SetPixbufProp(m_rendererIcon
, m_value
.GetIcon().GetPixbuf()); 
2816 bool wxDataViewIconTextRenderer::GetValue(wxVariant
& value
) const 
2819     if ( !GetTextValue(str
) ) 
2822     // user doesn't have any way to edit the icon so leave it unchanged 
2823     value 
<< wxDataViewIconText(str
, m_value
.GetIcon()); 
2829 wxDataViewIconTextRenderer::GtkOnCellChanged(const wxVariant
& value
, 
2830                                              const wxDataViewItem
& item
, 
2833     // we receive just the text part of our value as it's the only one which 
2834     // can be edited, but we need the full wxDataViewIconText value for the 
2836     wxVariant valueIconText
; 
2837     valueIconText 
<< wxDataViewIconText(value
.GetString(), m_value
.GetIcon()); 
2838     wxDataViewTextRenderer::GtkOnCellChanged(valueIconText
, item
, col
); 
2841 // --------------------------------------------------------- 
2843 // --------------------------------------------------------- 
2847 gtk_dataview_header_button_press_callback( GtkWidget 
*WXUNUSED(widget
), 
2848                                            GdkEventButton 
*gdk_event
, 
2849                                            wxDataViewColumn 
*column 
) 
2851     if (gdk_event
->type 
!= GDK_BUTTON_PRESS
) 
2854     if (gdk_event
->button 
== 1) 
2856         gs_lastLeftClickHeader 
= column
; 
2858         wxDataViewCtrl 
*dv 
= column
->GetOwner(); 
2859         wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK
, dv
->GetId() ); 
2860         event
.SetDataViewColumn( column 
); 
2861         event
.SetModel( dv
->GetModel() ); 
2862         if (dv
->HandleWindowEvent( event 
)) 
2866     if (gdk_event
->button 
== 3) 
2868         wxDataViewCtrl 
*dv 
= column
->GetOwner(); 
2869         wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK
, dv
->GetId() ); 
2870         event
.SetDataViewColumn( column 
); 
2871         event
.SetModel( dv
->GetModel() ); 
2872         if (dv
->HandleWindowEvent( event 
)) 
2882 static void wxGtkTreeCellDataFunc( GtkTreeViewColumn 
*WXUNUSED(column
), 
2883                             GtkCellRenderer 
*renderer
, 
2884                             GtkTreeModel 
*model
, 
2888     g_return_if_fail (GTK_IS_WX_TREE_MODEL (model
)); 
2889     GtkWxTreeModel 
*tree_model 
= (GtkWxTreeModel 
*) model
; 
2891     wxDataViewRenderer 
*cell 
= (wxDataViewRenderer
*) data
; 
2893     wxDataViewItem 
item( (void*) iter
->user_data 
); 
2895     wxDataViewModel 
*wx_model 
= tree_model
->internal
->GetDataViewModel(); 
2897     if (!wx_model
->IsVirtualListModel()) 
2900         if (wx_model
->IsContainer( item 
)) 
2902             visible 
= wx_model
->HasContainerColumns( item 
) || 
2903                         (cell
->GetOwner()->GetModelColumn() == 0); 
2910         GValue gvalue 
= { 0, }; 
2911         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
2912         g_value_set_boolean( &gvalue
, visible 
); 
2913         g_object_set_property( G_OBJECT(renderer
), "visible", &gvalue 
); 
2914         g_value_unset( &gvalue 
); 
2921     wx_model
->GetValue( value
, item
, cell
->GetOwner()->GetModelColumn() ); 
2923     if (value
.GetType() != cell
->GetVariantType()) 
2925         wxLogError( wxT("Wrong type, required: %s but: %s"), 
2926                     value
.GetType().c_str(), 
2927                     cell
->GetVariantType().c_str() ); 
2930     cell
->SetValue( value 
); 
2933     // deal with attributes: if the renderer doesn't support them at all, we 
2934     // don't even need to query the model for them 
2935     if ( !cell
->GtkSupportsAttrs() ) 
2938     // it can support attributes so check if this item has any 
2939     wxDataViewItemAttr attr
; 
2940     if ( wx_model
->GetAttr( item
, cell
->GetOwner()->GetModelColumn(), attr 
) 
2941             || !cell
->GtkIsUsingDefaultAttrs() ) 
2943         bool usingDefaultAttrs 
= !cell
->GtkSetAttr(attr
); 
2944         cell
->GtkSetUsingDefaultAttrs(usingDefaultAttrs
); 
2946     // else: no custom attributes specified and we're already using the default 
2947     //       ones -- nothing to do 
2952 #include <wx/listimpl.cpp> 
2953 WX_DEFINE_LIST(wxDataViewColumnList
) 
2955 wxDataViewColumn::wxDataViewColumn( const wxString 
&title
, wxDataViewRenderer 
*cell
, 
2956                                     unsigned int model_column
, int width
, 
2957                                     wxAlignment align
, int flags 
) 
2958     : wxDataViewColumnBase( cell
, model_column 
) 
2960     Init( align
, flags
, width 
); 
2965 wxDataViewColumn::wxDataViewColumn( const wxBitmap 
&bitmap
, wxDataViewRenderer 
*cell
, 
2966                                     unsigned int model_column
, int width
, 
2967                                     wxAlignment align
, int flags 
) 
2968     : wxDataViewColumnBase( bitmap
, cell
, model_column 
) 
2970     Init( align
, flags
, width 
); 
2972     SetBitmap( bitmap 
); 
2975 void wxDataViewColumn::Init(wxAlignment align
, int flags
, int width
) 
2977     m_isConnected 
= false; 
2979     GtkTreeViewColumn 
*column 
= gtk_tree_view_column_new(); 
2980     m_column 
= (GtkWidget
*) column
; 
2983     SetAlignment( align 
); 
2987     // Create container for icon and label 
2988     GtkWidget 
*box 
= gtk_hbox_new( FALSE
, 1 ); 
2989     gtk_widget_show( box 
); 
2990     // gtk_container_set_border_width((GtkContainer*)box, 2); 
2991     m_image 
= gtk_image_new(); 
2992     gtk_box_pack_start(GTK_BOX(box
), m_image
, FALSE
, FALSE
, 1); 
2993     m_label 
= gtk_label_new(""); 
2994     gtk_box_pack_end( GTK_BOX(box
), GTK_WIDGET(m_label
), FALSE
, FALSE
, 1 ); 
2995     gtk_tree_view_column_set_widget( column
, box 
); 
2997     wxDataViewRenderer 
* const colRenderer 
= GetRenderer(); 
2998     GtkCellRenderer 
* const cellRenderer 
= colRenderer
->GetGtkHandle(); 
3000     colRenderer
->GtkPackIntoColumn(column
); 
3002     gtk_tree_view_column_set_cell_data_func( column
, cellRenderer
, 
3003         wxGtkTreeCellDataFunc
, (gpointer
) colRenderer
, NULL 
); 
3006 void wxDataViewColumn::OnInternalIdle() 
3011     if (GTK_WIDGET_REALIZED(GetOwner()->m_treeview
)) 
3013         GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
3016             g_signal_connect(column
->button
, "button_press_event", 
3017                       G_CALLBACK (gtk_dataview_header_button_press_callback
), this); 
3019             // otherwise the event will be blocked by GTK+ 
3020             gtk_tree_view_column_set_clickable( column
, TRUE 
);  
3022             m_isConnected 
= true; 
3027 void wxDataViewColumn::SetOwner( wxDataViewCtrl 
*owner 
) 
3029     wxDataViewColumnBase::SetOwner( owner 
); 
3031     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
3033     gtk_tree_view_column_set_title( column
, wxGTK_CONV_FONT(GetTitle(), GetOwner()->GetFont() ) ); 
3036 void wxDataViewColumn::SetTitle( const wxString 
&title 
) 
3038     wxDataViewCtrl 
*ctrl 
= GetOwner(); 
3039     gtk_label_set_text( GTK_LABEL(m_label
), ctrl 
? wxGTK_CONV_FONT(title
, ctrl
->GetFont()) 
3040                                                  : wxGTK_CONV_SYS(title
) ); 
3042         gtk_widget_hide( m_label 
); 
3044         gtk_widget_show( m_label 
); 
3047 wxString 
wxDataViewColumn::GetTitle() const 
3049     return wxGTK_CONV_BACK_FONT( 
3050             gtk_label_get_text( GTK_LABEL(m_label
) ), 
3051             GetOwner()->GetFont() 
3055 void wxDataViewColumn::SetBitmap( const wxBitmap 
&bitmap 
) 
3057     wxDataViewColumnBase::SetBitmap( bitmap 
); 
3061         GtkImage 
*gtk_image 
= GTK_IMAGE(m_image
); 
3063         GdkBitmap 
*mask 
= NULL
; 
3064         if (bitmap
.GetMask()) 
3065             mask 
= bitmap
.GetMask()->GetBitmap(); 
3067         if (bitmap
.HasPixbuf()) 
3069             gtk_image_set_from_pixbuf(GTK_IMAGE(gtk_image
), 
3070                                       bitmap
.GetPixbuf()); 
3074             gtk_image_set_from_pixmap(GTK_IMAGE(gtk_image
), 
3075                                       bitmap
.GetPixmap(), mask
); 
3077         gtk_widget_show( m_image 
); 
3081         gtk_widget_hide( m_image 
); 
3085 void wxDataViewColumn::SetHidden( bool hidden 
) 
3087     gtk_tree_view_column_set_visible( GTK_TREE_VIEW_COLUMN(m_column
), !hidden 
); 
3090 void wxDataViewColumn::SetResizeable( bool resizeable 
) 
3092     gtk_tree_view_column_set_resizable( GTK_TREE_VIEW_COLUMN(m_column
), resizeable 
); 
3095 void wxDataViewColumn::SetAlignment( wxAlignment align 
) 
3097     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
3099     gfloat xalign 
= 0.0; 
3100     if (align 
== wxALIGN_RIGHT
) 
3102     if (align 
== wxALIGN_CENTER_HORIZONTAL 
|| 
3103         align 
== wxALIGN_CENTER
) 
3106     gtk_tree_view_column_set_alignment( column
, xalign 
); 
3108     if (m_renderer 
&& m_renderer
->GetAlignment() == -1) 
3109         m_renderer
->GtkUpdateAlignment(); 
3112 wxAlignment 
wxDataViewColumn::GetAlignment() const 
3114     gfloat xalign 
= gtk_tree_view_column_get_alignment( GTK_TREE_VIEW_COLUMN(m_column
) ); 
3117         return wxALIGN_RIGHT
; 
3119         return wxALIGN_CENTER_HORIZONTAL
; 
3121     return wxALIGN_LEFT
; 
3124 void wxDataViewColumn::SetSortable( bool sortable 
) 
3126     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
3130         gtk_tree_view_column_set_sort_column_id( column
, GetModelColumn() ); 
3134         gtk_tree_view_column_set_sort_column_id( column
, -1 ); 
3135         gtk_tree_view_column_set_sort_indicator( column
, FALSE 
); 
3136         gtk_tree_view_column_set_clickable( column
, FALSE 
); 
3140 bool wxDataViewColumn::IsSortable() const 
3142     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
3143     return gtk_tree_view_column_get_clickable( column 
); 
3146 void wxDataViewColumn::SetAsSortKey( bool WXUNUSED(sort
) ) 
3148     // it might not make sense to have this function in wxHeaderColumn at 
3149     // all in fact, changing of the sort order should only be done using the 
3150     // associated control API 
3151     wxFAIL_MSG( "not implemented" ); 
3154 bool wxDataViewColumn::IsSortKey() const 
3156     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
3157     return gtk_tree_view_column_get_sort_indicator( column 
); 
3160 bool wxDataViewColumn::IsResizeable() const 
3162     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
3163     return gtk_tree_view_column_get_resizable( column 
); 
3166 bool wxDataViewColumn::IsHidden() const 
3168     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
3169     return !gtk_tree_view_column_get_visible( column 
); 
3172 void wxDataViewColumn::SetSortOrder( bool ascending 
) 
3174     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
3177         gtk_tree_view_column_set_sort_order( column
, GTK_SORT_ASCENDING 
); 
3179         gtk_tree_view_column_set_sort_order( column
, GTK_SORT_DESCENDING 
); 
3181     gtk_tree_view_column_set_sort_indicator( column
, TRUE 
); 
3184 bool wxDataViewColumn::IsSortOrderAscending() const 
3186     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
3188     return (gtk_tree_view_column_get_sort_order( column 
) != GTK_SORT_DESCENDING
); 
3191 void wxDataViewColumn::SetMinWidth( int width 
) 
3193     gtk_tree_view_column_set_min_width( GTK_TREE_VIEW_COLUMN(m_column
), width 
); 
3196 int wxDataViewColumn::GetMinWidth() const 
3198     return gtk_tree_view_column_get_min_width( GTK_TREE_VIEW_COLUMN(m_column
) ); 
3201 int wxDataViewColumn::GetWidth() const 
3203     return gtk_tree_view_column_get_width( GTK_TREE_VIEW_COLUMN(m_column
) ); 
3206 void wxDataViewColumn::SetWidth( int width 
) 
3211         gtk_tree_view_column_set_sizing( GTK_TREE_VIEW_COLUMN(m_column
), GTK_TREE_VIEW_COLUMN_FIXED 
); 
3213         // TODO find a better calculation 
3214         gtk_tree_view_column_set_fixed_width( GTK_TREE_VIEW_COLUMN(m_column
), wxDVC_DEFAULT_WIDTH 
); 
3216         // this is unpractical for large numbers of items and disables 
3217         // user resizing, which is totally unexpected 
3218         gtk_tree_view_column_set_sizing( GTK_TREE_VIEW_COLUMN(m_column
), GTK_TREE_VIEW_COLUMN_AUTOSIZE 
); 
3223         gtk_tree_view_column_set_sizing( GTK_TREE_VIEW_COLUMN(m_column
), GTK_TREE_VIEW_COLUMN_FIXED 
); 
3225         gtk_tree_view_column_set_fixed_width( GTK_TREE_VIEW_COLUMN(m_column
), width 
); 
3229 void wxDataViewColumn::SetReorderable( bool reorderable 
) 
3231     gtk_tree_view_column_set_reorderable( GTK_TREE_VIEW_COLUMN(m_column
), reorderable 
); 
3234 bool wxDataViewColumn::IsReorderable() const 
3236     return gtk_tree_view_column_get_reorderable( GTK_TREE_VIEW_COLUMN(m_column
) ); 
3239 //----------------------------------------------------------------------------- 
3240 // wxGtkTreeModelNode 
3241 //----------------------------------------------------------------------------- 
3244 class wxGtkTreeModelChildWithPos
 
3252 int wxGtkTreeModelChildWithPosCmp( const void* data1
, const void* data2
, const void* user_data 
) 
3254     const wxGtkTreeModelChildWithPos
* child1 
= (const wxGtkTreeModelChildWithPos
*) data1
; 
3255     const wxGtkTreeModelChildWithPos
* child2 
= (const wxGtkTreeModelChildWithPos
*) data2
; 
3256     const wxDataViewCtrlInternal 
*internal 
= (const wxDataViewCtrlInternal 
*) user_data
; 
3257     int ret 
= internal
->GetDataViewModel()->Compare( child1
->id
, child2
->id
, 
3258         internal
->GetSortColumn(), (internal
->GetSortOrder() == GTK_SORT_DESCENDING
) ); 
3264 int LINKAGEMODE 
wxGtkTreeModelChildPtrCmp( void*** data1
, void*** data2 
) 
3266     return gs_internal
->GetDataViewModel()->Compare( **data1
, **data2
, 
3267         gs_internal
->GetSortColumn(), (gs_internal
->GetSortOrder() == GTK_SORT_ASCENDING
) ); 
3270 WX_DEFINE_ARRAY_PTR( void**, wxGtkTreeModelChildrenPtr 
); 
3273 void wxGtkTreeModelNode::Resort() 
3275     size_t child_count 
= GetChildCount(); 
3276     if (child_count 
== 0) 
3279     size_t node_count 
= GetNodesCount(); 
3281     if (child_count 
== 1) 
3283         if (node_count 
== 1) 
3285             wxGtkTreeModelNode 
*node 
= m_nodes
.Item( 0 ); 
3291     gint 
*new_order 
= new gint
[child_count
]; 
3294     // m_children has the original *void 
3295     // ptrs points to these 
3296     wxGtkTreeModelChildrenPtr ptrs
; 
3298     for (i 
= 0; i 
< child_count
; i
++) 
3299        ptrs
.Add( &(m_children
[i
]) ); 
3301     gs_internal 
= m_internal
; 
3302     ptrs
.Sort( &wxGtkTreeModelChildPtrCmp 
); 
3304     wxGtkTreeModelChildren temp
; 
3305     void** base_ptr 
= &(m_children
[0]); 
3306     // Transfer positions to new_order array and 
3308     for (i 
= 0; i 
< child_count
; i
++) 
3310         new_order
[i
] = ptrs
[i
] - base_ptr
; 
3311         temp
.Add( *ptrs
[i
] ); 
3314     // Transfer IDs back to m_children 
3316     WX_APPEND_ARRAY( temp
, m_children 
); 
3321     // Build up array with IDs and original positions 
3322     wxGtkTreeModelChildWithPos
* temp 
= new wxGtkTreeModelChildWithPos
[child_count
]; 
3324     for (i 
= 0; i 
< child_count
; i
++) 
3327        temp
[i
].id 
= m_children
[i
]; 
3329     // Sort array keeping original positions 
3330     wxQsort( temp
, child_count
, sizeof(wxGtkTreeModelChildWithPos
), 
3331              &wxGtkTreeModelChildWithPosCmp
, m_internal 
); 
3332     // Transfer positions to new_order array and 
3333     // IDs to m_children 
3335     for (i 
= 0; i 
< child_count
; i
++) 
3337        new_order
[i
] = temp
[i
].pos
; 
3338        m_children
.Add( temp
[i
].id 
); 
3347     wxGtkTreeModelChildren temp
; 
3348     WX_APPEND_ARRAY( temp
, m_children 
); 
3350     gs_internal 
= m_internal
; 
3351     m_children
.Sort( &wxGtkTreeModelChildCmp 
); 
3354     for (pos 
= 0; pos 
< child_count
; pos
++) 
3356         void *id 
= m_children
.Item( pos 
); 
3357         int old_pos 
= temp
.Index( id 
); 
3358         new_order
[pos
] = old_pos
; 
3362     GtkTreeModel 
*gtk_tree_model 
= GTK_TREE_MODEL( m_internal
->GetGtkModel() ); 
3365     iter
.user_data 
= GetItem().GetID(); 
3366     iter
.stamp 
= m_internal
->GetGtkModel()->stamp
; 
3368     gtk_tree_model_rows_reordered( gtk_tree_model
, 
3369             wxGtkTreePath(m_internal
->get_path(&iter
)), &iter
, new_order 
); 
3371     delete [] new_order
; 
3374     for (pos 
= 0; pos 
< node_count
; pos
++) 
3376         wxGtkTreeModelNode 
*node 
= m_nodes
.Item( pos 
); 
3381 //----------------------------------------------------------------------------- 
3382 // wxDataViewCtrlInternal 
3383 //----------------------------------------------------------------------------- 
3385 wxDataViewCtrlInternal::wxDataViewCtrlInternal( wxDataViewCtrl 
*owner
, wxDataViewModel 
*wx_model 
) 
3388     m_wx_model 
= wx_model
; 
3392     m_sort_order 
= GTK_SORT_ASCENDING
; 
3394     m_dataview_sort_column 
= NULL
; 
3396     m_dragDataObject 
= NULL
; 
3397     m_dropDataObject 
= NULL
; 
3401     m_gtk_model 
= wxgtk_tree_model_new(); 
3402     m_gtk_model
->internal 
= this; 
3404     m_notifier 
= new wxGtkDataViewModelNotifier( wx_model
, this ); 
3406     wx_model
->AddNotifier( m_notifier 
); 
3408     // g_object_unref( gtk_model ); ??? 
3410     if (!m_wx_model
->IsVirtualListModel()) 
3413     gtk_tree_view_set_model( GTK_TREE_VIEW(m_owner
->GtkGetTreeView()), GTK_TREE_MODEL(m_gtk_model
) ); 
3416 wxDataViewCtrlInternal::~wxDataViewCtrlInternal() 
3418     m_wx_model
->RemoveNotifier( m_notifier 
); 
3420     // remove the model from the GtkTreeView before it gets destroyed  
3421     gtk_tree_view_set_model( GTK_TREE_VIEW( m_owner
->GtkGetTreeView() ), NULL 
); 
3423     g_object_unref( m_gtk_model 
); 
3425     delete m_dragDataObject
; 
3426     delete m_dropDataObject
; 
3429 void wxDataViewCtrlInternal::ScheduleRefresh() 
3434 void wxDataViewCtrlInternal::OnInternalIdle() 
3438         GtkWidget 
*widget 
= m_owner
->GtkGetTreeView(); 
3439         gtk_widget_queue_draw( widget 
); 
3444 void wxDataViewCtrlInternal::InitTree() 
3446     wxDataViewItem item
; 
3447     m_root 
= new wxGtkTreeModelNode( NULL
, item
, this ); 
3449     BuildBranch( m_root 
); 
3452 void wxDataViewCtrlInternal::BuildBranch( wxGtkTreeModelNode 
*node 
) 
3454     if (node
->GetChildCount() == 0) 
3456         wxDataViewItemArray children
; 
3457         unsigned int count 
= m_wx_model
->GetChildren( node
->GetItem(), children 
); 
3460         for (pos 
= 0; pos 
< count
; pos
++) 
3462             wxDataViewItem child 
= children
[pos
]; 
3464             if (m_wx_model
->IsContainer( child 
)) 
3465                 node
->AddNode( new wxGtkTreeModelNode( node
, child
, this ) ); 
3467                 node
->AddLeave( child
.GetID() ); 
3469             // Don't send any events here 
3476 bool wxDataViewCtrlInternal::EnableDragSource( const wxDataFormat 
&format 
) 
3478     wxGtkString 
atom_str( gdk_atom_name( format  
) ); 
3479     m_dragSourceTargetEntryTarget 
= wxCharBuffer( atom_str 
); 
3481     m_dragSourceTargetEntry
.target 
=  m_dragSourceTargetEntryTarget
.data(); 
3482     m_dragSourceTargetEntry
.flags 
= 0; 
3483     m_dragSourceTargetEntry
.info 
= static_cast<guint
>(-1); 
3485     gtk_tree_view_enable_model_drag_source( GTK_TREE_VIEW(m_owner
->GtkGetTreeView() ), 
3486        GDK_BUTTON1_MASK
, &m_dragSourceTargetEntry
, 1, (GdkDragAction
) GDK_ACTION_COPY 
); 
3491 bool wxDataViewCtrlInternal::EnableDropTarget( const wxDataFormat 
&format 
) 
3493     wxGtkString 
atom_str( gdk_atom_name( format  
) ); 
3494     m_dropTargetTargetEntryTarget 
= wxCharBuffer( atom_str 
); 
3496     m_dropTargetTargetEntry
.target 
=  m_dropTargetTargetEntryTarget
.data(); 
3497     m_dropTargetTargetEntry
.flags 
= 0; 
3498     m_dropTargetTargetEntry
.info 
= static_cast<guint
>(-1); 
3500     gtk_tree_view_enable_model_drag_dest( GTK_TREE_VIEW(m_owner
->GtkGetTreeView() ), 
3501        &m_dropTargetTargetEntry
, 1, (GdkDragAction
) GDK_ACTION_COPY 
); 
3506 gboolean 
wxDataViewCtrlInternal::row_draggable( GtkTreeDragSource 
*WXUNUSED(drag_source
), 
3509     delete m_dragDataObject
; 
3511     wxDataViewItem 
item(GetOwner()->GTKPathToItem(path
)); 
3515     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_BEGIN_DRAG
, m_owner
->GetId() ); 
3516     event
.SetEventObject( m_owner 
); 
3517     event
.SetItem( item 
); 
3518     event
.SetModel( m_wx_model 
); 
3519     if (!m_owner
->HandleWindowEvent( event 
)) 
3522     if (!event
.IsAllowed()) 
3525     wxDataObject 
*obj 
= event
.GetDataObject(); 
3529     m_dragDataObject 
= obj
; 
3535 wxDataViewCtrlInternal::drag_data_delete(GtkTreeDragSource 
*WXUNUSED(drag_source
), 
3536                                          GtkTreePath 
*WXUNUSED(path
)) 
3541 gboolean 
wxDataViewCtrlInternal::drag_data_get( GtkTreeDragSource 
*WXUNUSED(drag_source
), 
3542     GtkTreePath 
*path
, GtkSelectionData 
*selection_data 
) 
3544     wxDataViewItem 
item(GetOwner()->GTKPathToItem(path
)); 
3548     if (!m_dragDataObject
->IsSupported( selection_data
->target 
)) 
3551     size_t size 
= m_dragDataObject
->GetDataSize( selection_data
->target 
); 
3555     void *buf 
= malloc( size 
); 
3557     gboolean res 
= FALSE
; 
3558     if (m_dragDataObject
->GetDataHere( selection_data
->target
, buf 
)) 
3562         gtk_selection_data_set( selection_data
, selection_data
->target
, 
3563             8, (const guchar
*) buf
, size 
); 
3572 wxDataViewCtrlInternal::drag_data_received(GtkTreeDragDest 
*WXUNUSED(drag_dest
), 
3574                                            GtkSelectionData 
*selection_data
) 
3576     wxDataViewItem 
item(GetOwner()->GTKPathToItem(path
)); 
3580     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_DROP
, m_owner
->GetId() ); 
3581     event
.SetEventObject( m_owner 
); 
3582     event
.SetItem( item 
); 
3583     event
.SetModel( m_wx_model 
); 
3584     event
.SetDataFormat( selection_data
->target 
); 
3585     event
.SetDataSize( selection_data
->length 
); 
3586     event
.SetDataBuffer( selection_data
->data 
); 
3587     if (!m_owner
->HandleWindowEvent( event 
)) 
3590     if (!event
.IsAllowed()) 
3597 wxDataViewCtrlInternal::row_drop_possible(GtkTreeDragDest 
*WXUNUSED(drag_dest
), 
3599                                           GtkSelectionData 
*selection_data
) 
3601     wxDataViewItem 
item(GetOwner()->GTKPathToItem(path
)); 
3605     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_DROP_POSSIBLE
, m_owner
->GetId() ); 
3606     event
.SetEventObject( m_owner 
); 
3607     event
.SetItem( item 
); 
3608     event
.SetModel( m_wx_model 
); 
3609     event
.SetDataFormat( selection_data
->target 
); 
3610     if (!m_owner
->HandleWindowEvent( event 
)) 
3613     if (!event
.IsAllowed()) 
3619 // notifications from wxDataViewModel 
3621 bool wxDataViewCtrlInternal::Cleared() 
3636 void wxDataViewCtrlInternal::Resort() 
3638     if (!m_wx_model
->IsVirtualListModel()) 
3644 bool wxDataViewCtrlInternal::ItemAdded( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
) 
3646     if (!m_wx_model
->IsVirtualListModel()) 
3648         wxGtkTreeModelNode 
*parent_node 
= FindNode( parent 
); 
3649         wxASSERT_MSG(parent_node
, 
3650             "Did you forget a call to ItemAdded()? The parent node is unknown to the wxGtkTreeModel"); 
3652         if (m_wx_model
->IsContainer( item 
)) 
3653             parent_node
->AddNode( new wxGtkTreeModelNode( parent_node
, item
, this ) ); 
3655             parent_node
->AddLeave( item
.GetID() ); 
3663 bool wxDataViewCtrlInternal::ItemDeleted( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
) 
3665     if (!m_wx_model
->IsVirtualListModel()) 
3667         wxGtkTreeModelNode 
*parent_node 
= FindNode( parent 
); 
3668         wxASSERT_MSG(parent_node
, 
3669             "Did you forget a call to ItemAdded()? The parent node is unknown to the wxGtkTreeModel"); 
3671         parent_node
->DeleteChild( item
.GetID() ); 
3679 bool wxDataViewCtrlInternal::ItemChanged( const wxDataViewItem 
&item 
) 
3681     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED
, m_owner
->GetId() ); 
3682     event
.SetEventObject( m_owner 
); 
3683     event
.SetModel( m_owner
->GetModel() ); 
3684     event
.SetItem( item 
); 
3685     m_owner
->HandleWindowEvent( event 
); 
3690 bool wxDataViewCtrlInternal::ValueChanged( const wxDataViewItem 
&item
, unsigned int col 
) 
3692     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED
, m_owner
->GetId() ); 
3693     event
.SetEventObject( m_owner 
); 
3694     event
.SetModel( m_owner
->GetModel() ); 
3695     event
.SetColumn( col 
); 
3696     event
.SetDataViewColumn( GetOwner()->GetColumn(col
) ); 
3697     event
.SetItem( item 
); 
3698     m_owner
->HandleWindowEvent( event 
); 
3705 GtkTreeModelFlags 
wxDataViewCtrlInternal::get_flags() 
3709     if ( m_wx_model
->IsListModel() ) 
3710         flags 
|= GTK_TREE_MODEL_LIST_ONLY
; 
3712     if ( !m_wx_model
->IsVirtualListModel() ) 
3713         flags 
|= GTK_TREE_MODEL_ITERS_PERSIST
; 
3715     return GtkTreeModelFlags(flags
); 
3718 gboolean 
wxDataViewCtrlInternal::get_iter( GtkTreeIter 
*iter
, GtkTreePath 
*path 
) 
3721     if (m_wx_model
->IsVirtualListModel()) 
3723         wxDataViewVirtualListModel 
*wx_model 
= (wxDataViewVirtualListModel
*) m_wx_model
; 
3725         unsigned int i 
= (unsigned int)gtk_tree_path_get_indices (path
)[0]; 
3727         if (i 
>= wx_model
->GetCount()) 
3730         iter
->stamp 
= m_gtk_model
->stamp
; 
3731         // user_data is just the index +1 
3732         iter
->user_data 
= (gpointer
) (i
+1); 
3738         int depth 
= gtk_tree_path_get_depth( path 
); 
3740         wxGtkTreeModelNode 
*node 
= m_root
; 
3743         for (i 
= 0; i 
< depth
; i
++) 
3745             BuildBranch( node 
); 
3747             gint pos 
= gtk_tree_path_get_indices (path
)[i
]; 
3748             if (pos 
< 0) return FALSE
; 
3749             if ((size_t)pos 
>= node
->GetChildCount()) return FALSE
; 
3751             void* id 
= node
->GetChildren().Item( (size_t) pos 
); 
3755                 iter
->stamp 
= m_gtk_model
->stamp
; 
3756                 iter
->user_data 
= id
; 
3760             size_t count 
= node
->GetNodes().GetCount(); 
3762             for (pos2 
= 0; pos2 
< count
; pos2
++) 
3764                 wxGtkTreeModelNode 
*child_node 
= node
->GetNodes().Item( pos2 
); 
3765                 if (child_node
->GetItem().GetID() == id
) 
3777 GtkTreePath 
*wxDataViewCtrlInternal::get_path( GtkTreeIter 
*iter 
) 
3779     // When this is called from ItemDeleted(), the item is already 
3780     // deleted in the model. 
3782     GtkTreePath 
*retval 
= gtk_tree_path_new (); 
3784     if (m_wx_model
->IsVirtualListModel()) 
3786         // iter is root, add nothing 
3787         if (!iter
->user_data
) 
3790         // user_data is just the index +1 
3791         int i 
= ( (wxUIntPtr
) iter
->user_data 
) -1; 
3792         gtk_tree_path_append_index (retval
, i
); 
3796         void *id 
= iter
->user_data
; 
3798         wxGtkTreeModelNode 
*node 
= FindParentNode( iter 
); 
3801             int pos 
= node
->GetChildren().Index( id 
); 
3803             gtk_tree_path_prepend_index( retval
, pos 
); 
3805             id 
= node
->GetItem().GetID(); 
3806             node 
= node
->GetParent(); 
3813 gboolean 
wxDataViewCtrlInternal::iter_next( GtkTreeIter 
*iter 
) 
3815     if (m_wx_model
->IsVirtualListModel()) 
3817         wxDataViewVirtualListModel 
*wx_model 
= (wxDataViewVirtualListModel
*) m_wx_model
; 
3819         // user_data is just the index +1 
3820         int n 
= ( (wxUIntPtr
) iter
->user_data 
) -1; 
3824             iter
->user_data 
= NULL
; 
3828         if (n 
>= (int) wx_model
->GetCount()-1) 
3830             iter
->user_data 
= NULL
; 
3834         // user_data is just the index +1 (+2 because we need the next) 
3835         iter
->user_data 
= (gpointer
) (n
+2); 
3839         wxGtkTreeModelNode 
*parent 
= FindParentNode( iter 
); 
3840         if( parent 
== NULL 
) 
3842             iter
->user_data 
= NULL
; 
3846         int pos 
= parent
->GetChildren().Index( iter
->user_data 
); 
3848         if (pos 
== (int) parent
->GetChildCount()-1) 
3850             iter
->user_data 
= NULL
; 
3854         iter
->user_data 
= parent
->GetChildren().Item( pos
+1 ); 
3860 gboolean 
wxDataViewCtrlInternal::iter_children( GtkTreeIter 
*iter
, GtkTreeIter 
*parent 
) 
3862     if (m_wx_model
->IsVirtualListModel()) 
3864         // this is a list, nodes have no children 
3868         iter
->stamp 
= m_gtk_model
->stamp
; 
3869         iter
->user_data 
= (gpointer
) 1; 
3877             if (m_root
->GetChildCount() == 0) return FALSE
; 
3878             iter
->stamp 
= m_gtk_model
->stamp
; 
3879             iter
->user_data 
= (gpointer
) m_root
->GetChildren().Item( 0 ); 
3884         wxDataViewItem item
; 
3886             item 
= wxDataViewItem( (void*) parent
->user_data 
); 
3888         if (!m_wx_model
->IsContainer( item 
)) 
3891         wxGtkTreeModelNode 
*parent_node 
= FindNode( parent 
); 
3892         wxASSERT_MSG(parent_node
, 
3893             "Did you forget a call to ItemAdded()? The parent node is unknown to the wxGtkTreeModel"); 
3895         BuildBranch( parent_node 
); 
3897         if (parent_node
->GetChildCount() == 0) 
3900         iter
->stamp 
= m_gtk_model
->stamp
; 
3901         iter
->user_data 
= (gpointer
) parent_node
->GetChildren().Item( 0 ); 
3907 gboolean 
wxDataViewCtrlInternal::iter_has_child( GtkTreeIter 
*iter 
) 
3909     if (m_wx_model
->IsVirtualListModel()) 
3911         wxDataViewVirtualListModel 
*wx_model 
= (wxDataViewVirtualListModel
*) m_wx_model
; 
3914             return (wx_model
->GetCount() > 0); 
3916         // this is a list, nodes have no children 
3922             return (m_root
->GetChildCount() > 0); 
3924         wxDataViewItem 
item( (void*) iter
->user_data 
); 
3926         bool is_container 
= m_wx_model
->IsContainer( item 
); 
3931         wxGtkTreeModelNode 
*node 
= FindNode( iter 
); 
3933             "Did you forget a call to ItemAdded()? The iterator is unknown to the wxGtkTreeModel"); 
3935         BuildBranch( node 
); 
3937         return (node
->GetChildCount() > 0); 
3941 gint 
wxDataViewCtrlInternal::iter_n_children( GtkTreeIter 
*iter 
) 
3943     if (m_wx_model
->IsVirtualListModel()) 
3945         wxDataViewVirtualListModel 
*wx_model 
= (wxDataViewVirtualListModel
*) m_wx_model
; 
3948             return (gint
) wx_model
->GetCount(); 
3955             return m_root
->GetChildCount(); 
3957         wxDataViewItem 
item( (void*) iter
->user_data 
); 
3959         if (!m_wx_model
->IsContainer( item 
)) 
3962         wxGtkTreeModelNode 
*parent_node 
= FindNode( iter 
); 
3963         wxASSERT_MSG(parent_node
, 
3964             "Did you forget a call to ItemAdded()? The parent node is unknown to the wxGtkTreeModel"); 
3966         BuildBranch( parent_node 
); 
3968         return parent_node
->GetChildCount(); 
3972 gboolean 
wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter 
*iter
, GtkTreeIter 
*parent
, gint n 
) 
3974     if (m_wx_model
->IsVirtualListModel()) 
3976         wxDataViewVirtualListModel 
*wx_model 
= (wxDataViewVirtualListModel
*) m_wx_model
; 
3984         if (n 
>= (gint
) wx_model
->GetCount()) 
3987         iter
->stamp 
= m_gtk_model
->stamp
; 
3988         // user_data is just the index +1 
3989         iter
->user_data 
= (gpointer
) (n
+1); 
3996         if (parent
) id 
= (void*) parent
->user_data
; 
3997         wxDataViewItem 
item( id 
); 
3999         if (!m_wx_model
->IsContainer( item 
)) 
4002         wxGtkTreeModelNode 
*parent_node 
= FindNode( parent 
); 
4003         wxASSERT_MSG(parent_node
, 
4004             "Did you forget a call to ItemAdded()? The parent node is unknown to the wxGtkTreeModel"); 
4006         BuildBranch( parent_node 
); 
4008         iter
->stamp 
= m_gtk_model
->stamp
; 
4009         iter
->user_data 
= parent_node
->GetChildren().Item( n 
); 
4015 gboolean 
wxDataViewCtrlInternal::iter_parent( GtkTreeIter 
*iter
, GtkTreeIter 
*child 
) 
4017     if (m_wx_model
->IsVirtualListModel()) 
4023         wxGtkTreeModelNode 
*node 
= FindParentNode( child 
); 
4027         iter
->stamp 
= m_gtk_model
->stamp
; 
4028         iter
->user_data 
= (gpointer
) node
->GetItem().GetID(); 
4034 // item can be deleted already in the model 
4035 int wxDataViewCtrlInternal::GetIndexOf( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
) 
4037     if (m_wx_model
->IsVirtualListModel()) 
4039         return wxPtrToUInt(item
.GetID()) - 1; 
4043         wxGtkTreeModelNode 
*parent_node 
= FindNode( parent 
); 
4044         wxGtkTreeModelChildren 
&children 
= parent_node
->GetChildren(); 
4046         for (j 
= 0; j 
< children
.GetCount(); j
++) 
4048             if (children
[j
] == item
.GetID()) 
4056 static wxGtkTreeModelNode
* 
4057 wxDataViewCtrlInternal_FindNode( wxDataViewModel 
* model
, wxGtkTreeModelNode 
*treeNode
, const wxDataViewItem 
&item 
) 
4063     list
.DeleteContents( true ); 
4064     wxDataViewItem 
it( item 
); 
4068         wxDataViewItem 
* pItem 
= new wxDataViewItem( it 
); 
4069         list
.Insert( pItem 
); 
4070         it 
= model
->GetParent( it 
); 
4073     wxGtkTreeModelNode 
* node 
= treeNode
; 
4074     for( ItemList::compatibility_iterator n 
= list
.GetFirst(); n
; n 
= n
->GetNext() ) 
4076         if( node 
&& node
->GetNodes().GetCount() != 0 ) 
4078             int len 
= node
->GetNodes().GetCount(); 
4079             wxGtkTreeModelNodes 
&nodes 
= node
->GetNodes(); 
4081             for( ; j 
< len
; j 
++) 
4083                 if( nodes
[j
]->GetItem() == *(n
->GetData())) 
4102 wxGtkTreeModelNode 
*wxDataViewCtrlInternal::FindNode( GtkTreeIter 
*iter 
) 
4107     wxDataViewItem 
item( (void*) iter
->user_data 
); 
4111     wxGtkTreeModelNode 
*result 
= wxDataViewCtrlInternal_FindNode( m_wx_model
, m_root
, item 
); 
4116         wxLogDebug( "Not found %p", iter->user_data ); 
4120     // TODO: remove this code 
4126 wxGtkTreeModelNode 
*wxDataViewCtrlInternal::FindNode( const wxDataViewItem 
&item 
) 
4131     wxGtkTreeModelNode 
*result 
= wxDataViewCtrlInternal_FindNode( m_wx_model
, m_root
, item 
); 
4136         wxLogDebug( "Not found %p", item.GetID() ); 
4140     // TODO: remove this code 
4146 static wxGtkTreeModelNode
* 
4147 wxDataViewCtrlInternal_FindParentNode( wxDataViewModel 
* model
, wxGtkTreeModelNode 
*treeNode
, const wxDataViewItem 
&item 
) 
4153     list
.DeleteContents( true ); 
4157     wxDataViewItem 
it( model
->GetParent( item 
) ); 
4160         wxDataViewItem 
* pItem 
= new wxDataViewItem( it 
); 
4161         list
.Insert( pItem 
); 
4162         it 
= model
->GetParent( it 
); 
4165     wxGtkTreeModelNode 
* node 
= treeNode
; 
4166     for( ItemList::compatibility_iterator n 
= list
.GetFirst(); n
; n 
= n
->GetNext() ) 
4168         if( node 
&& node
->GetNodes().GetCount() != 0 ) 
4170             int len 
= node
->GetNodes().GetCount(); 
4171             wxGtkTreeModelNodes nodes 
= node
->GetNodes(); 
4173             for( ; j 
< len
; j 
++) 
4175                 if( nodes
[j
]->GetItem() == *(n
->GetData())) 
4190     //Examine whether the node is item's parent node 
4191     int len 
= node
->GetChildCount(); 
4192     for( int i 
= 0; i 
< len 
; i 
++ ) 
4194         if( node
->GetChildren().Item( i 
) == item
.GetID() ) 
4200 wxGtkTreeModelNode 
*wxDataViewCtrlInternal::FindParentNode( GtkTreeIter 
*iter 
) 
4205     wxDataViewItem 
item( (void*) iter
->user_data 
); 
4209     return wxDataViewCtrlInternal_FindParentNode( m_wx_model
, m_root
, item 
); 
4212 wxGtkTreeModelNode 
*wxDataViewCtrlInternal::FindParentNode( const wxDataViewItem 
&item 
) 
4217     return wxDataViewCtrlInternal_FindParentNode( m_wx_model
, m_root
, item 
); 
4220 //----------------------------------------------------------------------------- 
4221 // wxDataViewCtrl signal callbacks 
4222 //----------------------------------------------------------------------------- 
4225 wxdataview_selection_changed_callback( GtkTreeSelection
* WXUNUSED(selection
), wxDataViewCtrl 
*dv 
) 
4227     if (!GTK_WIDGET_REALIZED(dv
->m_widget
)) 
4230     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED
, dv
->GetId() ); 
4231     event
.SetItem( dv
->GetSelection() ); 
4232     event
.SetModel( dv
->GetModel() ); 
4233     dv
->HandleWindowEvent( event 
); 
4237 wxdataview_row_activated_callback( GtkTreeView
* WXUNUSED(treeview
), GtkTreePath 
*path
, 
4238                                    GtkTreeViewColumn 
*WXUNUSED(column
), wxDataViewCtrl 
*dv 
) 
4240     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED
, dv
->GetId() ); 
4242     wxDataViewItem 
item(dv
->GTKPathToItem(path
)); 
4243     event
.SetItem( item 
); 
4244     event
.SetModel( dv
->GetModel() ); 
4245     dv
->HandleWindowEvent( event 
); 
4249 wxdataview_test_expand_row_callback( GtkTreeView
* WXUNUSED(treeview
), GtkTreeIter
* iter
, 
4250                                      GtkTreePath 
*WXUNUSED(path
), wxDataViewCtrl 
*dv 
) 
4252     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING
, dv
->GetId() ); 
4254     wxDataViewItem 
item( (void*) iter
->user_data 
);; 
4255     event
.SetItem( item 
); 
4256     event
.SetModel( dv
->GetModel() ); 
4257     dv
->HandleWindowEvent( event 
); 
4259     return !event
.IsAllowed(); 
4263 wxdataview_row_expanded_callback( GtkTreeView
* WXUNUSED(treeview
), GtkTreeIter
* iter
, 
4264                                   GtkTreePath 
*WXUNUSED(path
), wxDataViewCtrl 
*dv 
) 
4266     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDED
, dv
->GetId() ); 
4268     wxDataViewItem 
item( (void*) iter
->user_data 
);; 
4269     event
.SetItem( item 
); 
4270     event
.SetModel( dv
->GetModel() ); 
4271     dv
->HandleWindowEvent( event 
); 
4275 wxdataview_test_collapse_row_callback( GtkTreeView
* WXUNUSED(treeview
), GtkTreeIter
* iter
, 
4276                                        GtkTreePath 
*WXUNUSED(path
), wxDataViewCtrl 
*dv 
) 
4278     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSING
, dv
->GetId() ); 
4280     wxDataViewItem 
item( (void*) iter
->user_data 
);; 
4281     event
.SetItem( item 
); 
4282     event
.SetModel( dv
->GetModel() ); 
4283     dv
->HandleWindowEvent( event 
); 
4285     return !event
.IsAllowed(); 
4289 wxdataview_row_collapsed_callback( GtkTreeView
* WXUNUSED(treeview
), GtkTreeIter
* iter
, 
4290                                    GtkTreePath 
*WXUNUSED(path
), wxDataViewCtrl 
*dv 
) 
4292     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSED
, dv
->GetId() ); 
4294     wxDataViewItem 
item( (void*) iter
->user_data 
);; 
4295     event
.SetItem( item 
); 
4296     event
.SetModel( dv
->GetModel() ); 
4297     dv
->HandleWindowEvent( event 
); 
4300 //----------------------------------------------------------------------------- 
4302 //----------------------------------------------------------------------------- 
4304 void wxDataViewCtrl::AddChildGTK(wxWindowGTK
* child
) 
4306     GtkWidget
* treeview 
= GtkGetTreeView(); 
4308     // Insert widget in GtkTreeView 
4309     if (GTK_WIDGET_REALIZED(treeview
)) 
4310         gtk_widget_set_parent_window( child
->m_widget
, 
4311           gtk_tree_view_get_bin_window( GTK_TREE_VIEW(treeview
) ) ); 
4312     gtk_widget_set_parent( child
->m_widget
, treeview 
); 
4316 void gtk_dataviewctrl_size_callback( GtkWidget 
*WXUNUSED(widget
), 
4317                                      GtkAllocation 
*WXUNUSED(gtk_alloc
), 
4318                                      wxDataViewCtrl 
*win 
) 
4320     wxWindowList::compatibility_iterator node 
= win
->GetChildren().GetFirst(); 
4323         wxWindow 
*child 
= node
->GetData(); 
4326         gtk_widget_size_request( child
->m_widget
, &req 
); 
4328         GtkAllocation alloc
; 
4329         alloc
.x 
= child
->m_x
; 
4330         alloc
.y 
= child
->m_y
; 
4331         alloc
.width 
= child
->m_width
; 
4332         alloc
.height 
= child
->m_height
; 
4333         gtk_widget_size_allocate( child
->m_widget
, &alloc 
); 
4335         node 
= node
->GetNext(); 
4340 //----------------------------------------------------------------------------- 
4341 // "motion_notify_event" 
4342 //----------------------------------------------------------------------------- 
4345 gtk_dataview_motion_notify_callback( GtkWidget 
*WXUNUSED(widget
), 
4346                                      GdkEventMotion 
*gdk_event
, 
4347                                      wxDataViewCtrl 
*dv 
) 
4349     if (gdk_event
->is_hint
) 
4353         GdkModifierType state
; 
4354         gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
4360     GtkTreeViewColumn 
*column 
= NULL
; 
4363     if (gtk_tree_view_get_path_at_pos( 
4364         GTK_TREE_VIEW(dv
->GtkGetTreeView()), 
4365         (int) gdk_event
->x
, (int) gdk_event
->y
, 
4374             dv
->GtkGetInternal()->get_iter( &iter
, path 
); 
4382 //----------------------------------------------------------------------------- 
4383 // "button_press_event" 
4384 //----------------------------------------------------------------------------- 
4387 gtk_dataview_button_press_callback( GtkWidget 
*WXUNUSED(widget
), 
4388                                     GdkEventButton 
*gdk_event
, 
4389                                     wxDataViewCtrl 
*dv 
) 
4391     if ((gdk_event
->button 
== 3) && (gdk_event
->type 
== GDK_BUTTON_PRESS
)) 
4394         GtkTreeViewColumn 
*column 
= NULL
; 
4397         if (gtk_tree_view_get_path_at_pos( 
4398             GTK_TREE_VIEW(dv
->GtkGetTreeView()), 
4399             (int) gdk_event
->x
, (int) gdk_event
->y
, 
4407                 wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU
, dv
->GetId() ); 
4408                 event
.SetItem(dv
->GTKPathToItem(path
)); 
4409                 event
.SetModel( dv
->GetModel() ); 
4410                 return dv
->HandleWindowEvent( event 
); 
4418 IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl
, wxDataViewCtrlBase
) 
4420 wxDataViewCtrl::~wxDataViewCtrl() 
4427 void wxDataViewCtrl::Init() 
4431     m_cols
.DeleteContents( true ); 
4434 bool wxDataViewCtrl::Create(wxWindow 
*parent
, 
4439                             const wxValidator
& validator
, 
4440                             const wxString
& name
) 
4442     if (!PreCreation( parent
, pos
, size 
) || 
4443         !CreateBase( parent
, id
, pos
, size
, style
, validator
, name 
)) 
4445         wxFAIL_MSG( wxT("wxDataViewCtrl creation failed") ); 
4449     m_widget 
= gtk_scrolled_window_new (NULL
, NULL
); 
4450     g_object_ref(m_widget
); 
4452     GTKScrolledWindowSetBorder(m_widget
, style
); 
4454     m_treeview 
= gtk_tree_view_new(); 
4455     gtk_container_add (GTK_CONTAINER (m_widget
), m_treeview
); 
4457     g_signal_connect (m_treeview
, "size_allocate", 
4458                      G_CALLBACK (gtk_dataviewctrl_size_callback
), this); 
4461     if (!gtk_check_version(2,6,0)) 
4463         bool fixed 
= (style 
& wxDV_VARIABLE_LINE_HEIGHT
) == 0; 
4464         gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview
), fixed 
); 
4468     if (style 
& wxDV_MULTIPLE
) 
4470         GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4471         gtk_tree_selection_set_mode( selection
, GTK_SELECTION_MULTIPLE 
); 
4474     gtk_tree_view_set_headers_visible( GTK_TREE_VIEW(m_treeview
), (style 
& wxDV_NO_HEADER
) == 0 ); 
4477     if (!gtk_check_version(2,10,0)) 
4479         GtkTreeViewGridLines grid 
= GTK_TREE_VIEW_GRID_LINES_NONE
; 
4481         if ((style 
& wxDV_HORIZ_RULES
) != 0 && 
4482             (style 
& wxDV_VERT_RULES
) != 0) 
4483             grid 
= GTK_TREE_VIEW_GRID_LINES_BOTH
; 
4484         else if (style 
& wxDV_VERT_RULES
) 
4485             grid 
= GTK_TREE_VIEW_GRID_LINES_VERTICAL
; 
4486         else if (style 
& wxDV_HORIZ_RULES
) 
4487             grid 
= GTK_TREE_VIEW_GRID_LINES_HORIZONTAL
; 
4489         if (grid 
!= GTK_TREE_VIEW_GRID_LINES_NONE
) 
4490             gtk_tree_view_set_grid_lines( GTK_TREE_VIEW(m_treeview
), grid 
); 
4494     gtk_tree_view_set_rules_hint( GTK_TREE_VIEW(m_treeview
), (style 
& wxDV_ROW_LINES
) != 0 ); 
4496     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_widget
), 
4497         GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
); 
4498     gtk_widget_show (m_treeview
); 
4500     m_parent
->DoAddChild( this ); 
4504     GtkEnableSelectionEvents(); 
4506     g_signal_connect_after (m_treeview
, "row-activated", 
4507                             G_CALLBACK (wxdataview_row_activated_callback
), this); 
4509     g_signal_connect (m_treeview
, "test-collapse-row", 
4510                             G_CALLBACK (wxdataview_test_collapse_row_callback
), this); 
4512     g_signal_connect_after (m_treeview
, "row-collapsed", 
4513                             G_CALLBACK (wxdataview_row_collapsed_callback
), this); 
4515     g_signal_connect (m_treeview
, "test-expand-row", 
4516                             G_CALLBACK (wxdataview_test_expand_row_callback
), this); 
4518     g_signal_connect_after (m_treeview
, "row-expanded", 
4519                             G_CALLBACK (wxdataview_row_expanded_callback
), this); 
4521     g_signal_connect (m_treeview
, "motion_notify_event", 
4522                       G_CALLBACK (gtk_dataview_motion_notify_callback
), this); 
4524     g_signal_connect (m_treeview
, "button_press_event", 
4525                       G_CALLBACK (gtk_dataview_button_press_callback
), this); 
4530 wxDataViewItem 
wxDataViewCtrl::GTKPathToItem(GtkTreePath 
*path
) const 
4533     return wxDataViewItem(path 
&& m_internal
->get_iter(&iter
, path
) 
4538 void wxDataViewCtrl::OnInternalIdle() 
4540     wxWindow::OnInternalIdle(); 
4542     m_internal
->OnInternalIdle(); 
4544     unsigned int cols 
= GetColumnCount(); 
4546     for (i 
= 0; i 
< cols
; i
++) 
4548         wxDataViewColumn 
*col 
= GetColumn( i 
); 
4549         col
->OnInternalIdle(); 
4552     if (m_ensureVisibleDefered
.IsOk()) 
4554         ExpandAncestors(m_ensureVisibleDefered
); 
4556         iter
.user_data 
= (gpointer
) m_ensureVisibleDefered
.GetID(); 
4557         wxGtkTreePath 
path(m_internal
->get_path( &iter 
)); 
4558         gtk_tree_view_scroll_to_cell( GTK_TREE_VIEW(m_treeview
), path
, NULL
, false, 0.0, 0.0 ); 
4559         m_ensureVisibleDefered 
= wxDataViewItem(0); 
4563 bool wxDataViewCtrl::AssociateModel( wxDataViewModel 
*model 
) 
4565     wxDELETE(m_internal
); 
4567     if (!wxDataViewCtrlBase::AssociateModel( model 
)) 
4571     if (!gtk_check_version(2,6,0)) 
4573         bool fixed 
= (((GetWindowStyle() & wxDV_VARIABLE_LINE_HEIGHT
) == 0) || (model
->IsVirtualListModel())); 
4574         gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview
), fixed 
); 
4578     m_internal 
= new wxDataViewCtrlInternal( this, model 
); 
4583 bool wxDataViewCtrl::EnableDragSource( const wxDataFormat 
&format 
) 
4585     return m_internal
->EnableDragSource( format 
); 
4588 bool wxDataViewCtrl::EnableDropTarget( const wxDataFormat 
&format 
) 
4590     return m_internal
->EnableDropTarget( format 
); 
4593 bool wxDataViewCtrl::AppendColumn( wxDataViewColumn 
*col 
) 
4595     if (!wxDataViewCtrlBase::AppendColumn(col
)) 
4598     m_cols
.Append( col 
); 
4601     if (!gtk_check_version(2,6,0)) 
4603         if (gtk_tree_view_column_get_sizing( GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()) ) != 
4604                GTK_TREE_VIEW_COLUMN_FIXED
) 
4605            gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview
), FALSE 
); 
4609     gtk_tree_view_append_column( GTK_TREE_VIEW(m_treeview
), 
4610                                  GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()) ); 
4615 bool wxDataViewCtrl::PrependColumn( wxDataViewColumn 
*col 
) 
4617     if (!wxDataViewCtrlBase::PrependColumn(col
)) 
4620     m_cols
.Insert( col 
); 
4623     if (!gtk_check_version(2,6,0)) 
4625         if (gtk_tree_view_column_get_sizing( GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()) ) != 
4626                GTK_TREE_VIEW_COLUMN_FIXED
) 
4627            gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview
), FALSE 
); 
4631     gtk_tree_view_insert_column( GTK_TREE_VIEW(m_treeview
), 
4632                                  GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()), 0 ); 
4637 bool wxDataViewCtrl::InsertColumn( unsigned int pos
, wxDataViewColumn 
*col 
) 
4639     if (!wxDataViewCtrlBase::InsertColumn(pos
,col
)) 
4642     m_cols
.Insert( pos
, col 
); 
4645     if (!gtk_check_version(2,6,0)) 
4647         if (gtk_tree_view_column_get_sizing( GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()) ) != 
4648                GTK_TREE_VIEW_COLUMN_FIXED
) 
4649            gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview
), FALSE 
); 
4653     gtk_tree_view_insert_column( GTK_TREE_VIEW(m_treeview
), 
4654                                  GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()), pos 
); 
4659 unsigned int wxDataViewCtrl::GetColumnCount() const 
4661     return m_cols
.GetCount(); 
4664 wxDataViewColumn
* wxDataViewCtrl::GetColumn( unsigned int pos 
) const 
4666     GtkTreeViewColumn 
*gtk_col 
= gtk_tree_view_get_column( GTK_TREE_VIEW(m_treeview
), pos 
); 
4670     wxDataViewColumnList::const_iterator iter
; 
4671     for (iter 
= m_cols
.begin(); iter 
!= m_cols
.end(); ++iter
) 
4673         wxDataViewColumn 
*col 
= *iter
; 
4674         if (GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()) == gtk_col
) 
4683 bool wxDataViewCtrl::DeleteColumn( wxDataViewColumn 
*column 
) 
4685     gtk_tree_view_remove_column( GTK_TREE_VIEW(m_treeview
), 
4686                                  GTK_TREE_VIEW_COLUMN(column
->GetGtkHandle()) ); 
4688     m_cols
.DeleteObject( column 
); 
4693 bool wxDataViewCtrl::ClearColumns() 
4695     wxDataViewColumnList::iterator iter
; 
4696     for (iter 
= m_cols
.begin(); iter 
!= m_cols
.end(); ++iter
) 
4698         wxDataViewColumn 
*col 
= *iter
; 
4699         gtk_tree_view_remove_column( GTK_TREE_VIEW(m_treeview
), 
4700                                      GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()) ); 
4708 int wxDataViewCtrl::GetColumnPosition( const wxDataViewColumn 
*column 
) const 
4710     GtkTreeViewColumn 
*gtk_column 
= GTK_TREE_VIEW_COLUMN(column
->GetConstGtkHandle()); 
4712     GList 
*list 
= gtk_tree_view_get_columns( GTK_TREE_VIEW(m_treeview
) ); 
4714     gint pos 
= g_list_index( list
, (gconstpointer
)  gtk_column 
); 
4716     g_list_free( list 
); 
4721 wxDataViewColumn 
*wxDataViewCtrl::GetSortingColumn() const 
4723     return m_internal
->GetDataViewSortColumn(); 
4726 void wxDataViewCtrl::Expand( const wxDataViewItem 
& item 
) 
4729     iter
.user_data 
= item
.GetID(); 
4730     wxGtkTreePath 
path(m_internal
->get_path( &iter 
)); 
4731     gtk_tree_view_expand_row( GTK_TREE_VIEW(m_treeview
), path
, false ); 
4734 void wxDataViewCtrl::Collapse( const wxDataViewItem 
& item 
) 
4737     iter
.user_data 
= item
.GetID(); 
4738     wxGtkTreePath 
path(m_internal
->get_path( &iter 
)); 
4739     gtk_tree_view_collapse_row( GTK_TREE_VIEW(m_treeview
), path 
); 
4742 bool wxDataViewCtrl::IsExpanded( const wxDataViewItem 
& item 
) const 
4745     iter
.user_data 
= item
.GetID(); 
4746     wxGtkTreePath 
path(m_internal
->get_path( &iter 
)); 
4747     return gtk_tree_view_row_expanded( GTK_TREE_VIEW(m_treeview
), path 
); 
4750 wxDataViewItem 
wxDataViewCtrl::DoGetCurrentItem() const 
4752     // The tree doesn't have any current item if it hadn't been created yet but 
4753     // it's arguably not an error to call this function in this case so just 
4754     // return an invalid item without asserting. 
4756         return wxDataViewItem(); 
4759     gtk_tree_view_get_cursor(GTK_TREE_VIEW(m_treeview
), path
.ByRef(), NULL
); 
4761     return GTKPathToItem(path
); 
4764 void wxDataViewCtrl::DoSetCurrentItem(const wxDataViewItem
& item
) 
4766     wxCHECK_RET( m_treeview
, 
4767                  "Current item can't be set before creating the control." ); 
4769     // We need to make sure the model knows about this item or the path would 
4770     // be invalid and gtk_tree_view_set_cursor() would silently do nothing. 
4771     ExpandAncestors(item
); 
4773     // We also need to preserve the existing selection from changing. 
4774     // Unfortunately the only way to do it seems to use our own selection 
4775     // function and forbid any selection changes during set cursor call. 
4776     wxGtkTreeSelectionLock
 
4777         lock(gtk_tree_view_get_selection(GTK_TREE_VIEW(m_treeview
))); 
4779     // Do move the cursor now. 
4781     iter
.user_data 
= item
.GetID(); 
4782     wxGtkTreePath 
path(m_internal
->get_path( &iter 
)); 
4784     gtk_tree_view_set_cursor(GTK_TREE_VIEW(m_treeview
), path
, NULL
, FALSE
); 
4787 wxDataViewItem 
wxDataViewCtrl::GetSelection() const 
4789     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4791     if (m_windowStyle 
& wxDV_MULTIPLE
) 
4793         // Report the first one 
4794         GtkTreeModel 
*model
; 
4795         GList 
*list 
= gtk_tree_selection_get_selected_rows( selection
, &model 
); 
4799             GtkTreePath 
*path 
= (GtkTreePath
*) list
->data
; 
4800             wxDataViewItem 
item(GTKPathToItem(path
)); 
4803             g_list_foreach( list
, (GFunc
) gtk_tree_path_free
, NULL 
); 
4804             g_list_free( list 
); 
4812         if (gtk_tree_selection_get_selected( selection
, NULL
, &iter 
)) 
4814             wxDataViewItem 
item( iter
.user_data 
); 
4819     return wxDataViewItem(0); 
4822 int wxDataViewCtrl::GetSelections( wxDataViewItemArray 
& sel 
) const 
4826     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4827     if (HasFlag(wxDV_MULTIPLE
)) 
4829         GtkTreeModel 
*model
; 
4830         GList 
*list 
= gtk_tree_selection_get_selected_rows( selection
, &model 
); 
4835             GtkTreePath 
*path 
= (GtkTreePath
*) list
->data
; 
4837             sel
.Add(GTKPathToItem(path
)); 
4839             list 
= g_list_next( list 
); 
4844         g_list_foreach( list
, (GFunc
) gtk_tree_path_free
, NULL 
); 
4845         g_list_free( list 
); 
4851         GtkTreeModel 
*model
; 
4853         gboolean has_selection 
= gtk_tree_selection_get_selected( selection
, &model
, &iter 
); 
4856             sel
.Add( wxDataViewItem( (void*) iter
.user_data
) ); 
4864 void wxDataViewCtrl::SetSelections( const wxDataViewItemArray 
& sel 
) 
4866     GtkDisableSelectionEvents(); 
4868     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4870     gtk_tree_selection_unselect_all( selection 
); 
4872     wxDataViewItem last_parent
; 
4875     for (i 
= 0; i 
< sel
.GetCount(); i
++) 
4877         wxDataViewItem item 
= sel
[i
]; 
4878         wxDataViewItem parent 
= GetModel()->GetParent( item 
); 
4881             if (parent 
!= last_parent
) 
4882                 ExpandAncestors(item
); 
4884         last_parent 
= parent
; 
4887         iter
.stamp 
= m_internal
->GetGtkModel()->stamp
; 
4888         iter
.user_data 
= (gpointer
) item
.GetID(); 
4889         gtk_tree_selection_select_iter( selection
, &iter 
); 
4892     GtkEnableSelectionEvents(); 
4895 void wxDataViewCtrl::Select( const wxDataViewItem 
& item 
) 
4897     ExpandAncestors(item
); 
4899     GtkDisableSelectionEvents(); 
4901     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4904     iter
.stamp 
= m_internal
->GetGtkModel()->stamp
; 
4905     iter
.user_data 
= (gpointer
) item
.GetID(); 
4906     gtk_tree_selection_select_iter( selection
, &iter 
); 
4908     GtkEnableSelectionEvents(); 
4911 void wxDataViewCtrl::Unselect( const wxDataViewItem 
& item 
) 
4913     GtkDisableSelectionEvents(); 
4915     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4918     iter
.stamp 
= m_internal
->GetGtkModel()->stamp
; 
4919     iter
.user_data 
= (gpointer
) item
.GetID(); 
4920     gtk_tree_selection_unselect_iter( selection
, &iter 
); 
4922     GtkEnableSelectionEvents(); 
4925 bool wxDataViewCtrl::IsSelected( const wxDataViewItem 
& item 
) const 
4927     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4930     iter
.stamp 
= m_internal
->GetGtkModel()->stamp
; 
4931     iter
.user_data 
= (gpointer
) item
.GetID(); 
4933     return gtk_tree_selection_iter_is_selected( selection
, &iter 
); 
4936 void wxDataViewCtrl::SelectAll() 
4938     GtkDisableSelectionEvents(); 
4940     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4942     gtk_tree_selection_select_all( selection 
); 
4944     GtkEnableSelectionEvents(); 
4947 void wxDataViewCtrl::UnselectAll() 
4949     GtkDisableSelectionEvents(); 
4951     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4953     gtk_tree_selection_unselect_all( selection 
); 
4955     GtkEnableSelectionEvents(); 
4958 void wxDataViewCtrl::EnsureVisible(const wxDataViewItem
& item
, 
4959                                    const wxDataViewColumn 
*WXUNUSED(column
)) 
4961     m_ensureVisibleDefered 
= item
; 
4962     ExpandAncestors(item
); 
4965     iter
.user_data 
= (gpointer
) item
.GetID(); 
4966     wxGtkTreePath 
path(m_internal
->get_path( &iter 
)); 
4967     gtk_tree_view_scroll_to_cell( GTK_TREE_VIEW(m_treeview
), path
, NULL
, false, 0.0, 0.0 ); 
4970 void wxDataViewCtrl::HitTest(const wxPoint
& WXUNUSED(point
), 
4971                              wxDataViewItem
& item
, 
4972                              wxDataViewColumn 
*& column
) const 
4974     item 
= wxDataViewItem(0); 
4979 wxDataViewCtrl::GetItemRect(const wxDataViewItem
& WXUNUSED(item
), 
4980                             const wxDataViewColumn 
*WXUNUSED(column
)) const 
4985 void wxDataViewCtrl::DoSetExpanderColumn() 
4987     gtk_tree_view_set_expander_column( GTK_TREE_VIEW(m_treeview
), 
4988         GTK_TREE_VIEW_COLUMN( GetExpanderColumn()->GetGtkHandle() ) ); 
4991 void wxDataViewCtrl::DoSetIndent() 
4995 void wxDataViewCtrl::GtkDisableSelectionEvents() 
4997     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4998     g_signal_handlers_disconnect_by_func( selection
, 
4999                             (gpointer
) (wxdataview_selection_changed_callback
), this); 
5002 void wxDataViewCtrl::GtkEnableSelectionEvents() 
5004     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
5005     g_signal_connect_after (selection
, "changed", 
5006                             G_CALLBACK (wxdataview_selection_changed_callback
), this); 
5009 // ---------------------------------------------------------------------------- 
5010 // visual attributes stuff 
5011 // ---------------------------------------------------------------------------- 
5015 wxDataViewCtrl::GetClassDefaultAttributes(wxWindowVariant 
WXUNUSED(variant
)) 
5017     return GetDefaultAttributesFromGTKWidget(gtk_tree_view_new
); 
5020 void wxDataViewCtrl::DoApplyWidgetStyle(GtkRcStyle 
*style
) 
5022     wxDataViewCtrlBase::DoApplyWidgetStyle(style
); 
5023     gtk_widget_modify_style(m_treeview
, style
); 
5026 #endif // !wxUSE_GENERICDATAVIEWCTRL 
5028 #endif // wxUSE_DATAVIEWCTRL