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 //----------------------------------------------------------------------------- 
  37 //----------------------------------------------------------------------------- 
  39 static wxDataViewCtrlInternal 
*gs_internal 
= NULL
; 
  41 class wxGtkTreeModelNode
; 
  44 typedef struct _GtkWxTreeModel       GtkWxTreeModel
; 
  47 //----------------------------------------------------------------------------- 
  48 // wxDataViewCtrlInternal 
  49 //----------------------------------------------------------------------------- 
  51 WX_DECLARE_LIST(wxDataViewItem
, ItemList
); 
  52 WX_DEFINE_LIST(ItemList
) 
  54 class WXDLLIMPEXP_ADV wxDataViewCtrlInternal
 
  57     wxDataViewCtrlInternal( wxDataViewCtrl 
*owner
, wxDataViewModel 
*wx_model
, GtkWxTreeModel 
*gtk_model 
); 
  58     ~wxDataViewCtrlInternal(); 
  61     GtkTreeModelFlags 
get_flags(); 
  62     gboolean 
get_iter( GtkTreeIter 
*iter
, GtkTreePath 
*path 
); 
  63     GtkTreePath 
*get_path( GtkTreeIter 
*iter
); 
  64     gboolean 
iter_next( GtkTreeIter 
*iter 
); 
  65     gboolean 
iter_children( GtkTreeIter 
*iter
, GtkTreeIter 
*parent
); 
  66     gboolean 
iter_has_child( GtkTreeIter 
*iter 
); 
  67     gint 
iter_n_children( GtkTreeIter 
*iter 
); 
  68     gboolean 
iter_nth_child( GtkTreeIter 
*iter
, GtkTreeIter 
*parent
, gint n 
); 
  69     gboolean 
iter_parent( GtkTreeIter 
*iter
, GtkTreeIter 
*child 
); 
  73     bool EnableDragSource( const wxDataFormat 
&format 
); 
  74     bool EnableDropTarget( const wxDataFormat 
&format 
); 
  76     gboolean 
row_draggable( GtkTreeDragSource 
*drag_source
, GtkTreePath 
*path 
); 
  77     gboolean 
drag_data_delete( GtkTreeDragSource 
*drag_source
, GtkTreePath
* path 
); 
  78     gboolean 
drag_data_get( GtkTreeDragSource 
*drag_source
, GtkTreePath 
*path
, 
  79         GtkSelectionData 
*selection_data 
); 
  80     gboolean 
drag_data_received( GtkTreeDragDest 
*drag_dest
, GtkTreePath 
*dest
, 
  81         GtkSelectionData 
*selection_data 
); 
  82     gboolean 
row_drop_possible( GtkTreeDragDest 
*drag_dest
, GtkTreePath 
*dest_path
, 
  83         GtkSelectionData 
*selection_data 
); 
  85     // notifactions from wxDataViewModel 
  86     bool ItemAdded( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
); 
  87     bool ItemDeleted( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
); 
  88     bool ItemChanged( const wxDataViewItem 
&item 
); 
  89     bool ValueChanged( const wxDataViewItem 
&item
, unsigned int col 
); 
  94     void SetSortOrder( GtkSortType sort_order 
) { m_sort_order 
= sort_order
; } 
  95     GtkSortType 
GetSortOrder() const            { return m_sort_order
; } 
  97     void SetSortColumn( int column 
)            { m_sort_column 
= column
; } 
  98     int GetSortColumn() const                   { return m_sort_column
; } 
 100     void SetDataViewSortColumn( wxDataViewColumn 
*column 
) { m_dataview_sort_column 
= column
; } 
 101     wxDataViewColumn 
*GetDataViewSortColumn()   { return m_dataview_sort_column
; } 
 103     bool IsSorted()                             { return (m_sort_column 
>= 0); } 
 106     wxDataViewModel
* GetDataViewModel() { return m_wx_model
; } 
 107     const wxDataViewModel
* GetDataViewModel() const { return m_wx_model
; } 
 108     wxDataViewCtrl
* GetOwner()          { return m_owner
; } 
 109     GtkWxTreeModel
* GetGtkModel()       { return m_gtk_model
; } 
 113     wxGtkTreeModelNode 
*FindNode( const wxDataViewItem 
&item 
); 
 114     wxGtkTreeModelNode 
*FindNode( GtkTreeIter 
*iter 
); 
 115     wxGtkTreeModelNode 
*FindParentNode( const wxDataViewItem 
&item 
); 
 116     wxGtkTreeModelNode 
*FindParentNode( GtkTreeIter 
*iter 
); 
 117     void BuildBranch( wxGtkTreeModelNode 
*branch 
); 
 120     wxGtkTreeModelNode   
*m_root
; 
 121     wxDataViewModel      
*m_wx_model
; 
 122     GtkWxTreeModel       
*m_gtk_model
; 
 123     wxDataViewCtrl       
*m_owner
; 
 124     GtkSortType           m_sort_order
; 
 125     wxDataViewColumn     
*m_dataview_sort_column
; 
 128     GtkTargetEntry        m_dragSourceTargetEntry
; 
 129     wxCharBuffer          m_dragSourceTargetEntryTarget
; 
 130     wxDataObject         
*m_dragDataObject
; 
 132     GtkTargetEntry        m_dropTargetTargetEntry
; 
 133     wxCharBuffer          m_dropTargetTargetEntryTarget
; 
 134     wxDataObject         
*m_dropDataObject
; 
 138 //----------------------------------------------------------------------------- 
 139 // wxGtkTreeModelNode 
 140 //----------------------------------------------------------------------------- 
 143 int LINKAGEMODE 
wxGtkTreeModelChildCmp( void** id1
, void** id2 
) 
 145     int ret 
= gs_internal
->GetDataViewModel()->Compare( *id1
, *id2
, 
 146         gs_internal
->GetSortColumn(), (gs_internal
->GetSortOrder() == GTK_SORT_ASCENDING
) ); 
 151 WX_DEFINE_ARRAY_PTR( wxGtkTreeModelNode
*, wxGtkTreeModelNodes 
); 
 152 WX_DEFINE_ARRAY_PTR( void*, wxGtkTreeModelChildren 
); 
 154 class wxGtkTreeModelNode
 
 157     wxGtkTreeModelNode( wxGtkTreeModelNode
* parent
, const wxDataViewItem 
&item
, 
 158                         wxDataViewCtrlInternal 
*internal 
) 
 162         m_internal 
= internal
; 
 165     ~wxGtkTreeModelNode() 
 167         size_t count 
= m_nodes
.GetCount(); 
 169         for (i 
= 0; i 
< count
; i
++) 
 171             wxGtkTreeModelNode 
*child 
= m_nodes
.Item( i 
); 
 176     unsigned int AddNode( wxGtkTreeModelNode
* child 
) 
 178             m_nodes
.Add( child 
); 
 180             void *id 
= child
->GetItem().GetID(); 
 182             m_children
.Add( id 
); 
 184             if (m_internal
->IsSorted() || m_internal
->GetDataViewModel()->HasDefaultCompare()) 
 186                 gs_internal 
= m_internal
; 
 187                 m_children
.Sort( &wxGtkTreeModelChildCmp 
); 
 188                 return m_children
.Index( id 
); 
 191             return m_children
.GetCount()-1; 
 194     unsigned int AddLeave( void* id 
) 
 196             m_children
.Add( id 
); 
 198             if (m_internal
->IsSorted() || m_internal
->GetDataViewModel()->HasDefaultCompare()) 
 200                 gs_internal 
= m_internal
; 
 201                 m_children
.Sort( &wxGtkTreeModelChildCmp 
); 
 202                 return m_children
.Index( id 
); 
 205             return m_children
.GetCount()-1; 
 208     void DeleteChild( void* id 
) 
 210             m_children
.Remove( id 
); 
 212             unsigned int count 
= m_nodes
.GetCount(); 
 214             for (pos 
= 0; pos 
< count
; pos
++) 
 216                 wxGtkTreeModelNode 
*node 
= m_nodes
.Item( pos 
); 
 217                 if (node
->GetItem().GetID() == id
) 
 219                     m_nodes
.RemoveAt( pos 
); 
 226     wxGtkTreeModelNode
* GetParent() 
 228     wxGtkTreeModelNodes 
&GetNodes() 
 230     wxGtkTreeModelChildren 
&GetChildren() 
 231         { return m_children
; } 
 233     unsigned int GetChildCount() const { return m_children
.GetCount(); } 
 234     unsigned int GetNodesCount() const { return m_nodes
.GetCount(); } 
 236     wxDataViewItem 
&GetItem() { return m_item
; } 
 237     wxDataViewCtrlInternal 
*GetInternal() { return m_internal
; } 
 242     wxGtkTreeModelNode         
*m_parent
; 
 243     wxGtkTreeModelNodes         m_nodes
; 
 244     wxGtkTreeModelChildren      m_children
; 
 245     wxDataViewItem              m_item
; 
 246     wxDataViewCtrlInternal     
*m_internal
; 
 250 //----------------------------------------------------------------------------- 
 252 //----------------------------------------------------------------------------- 
 254 extern bool   g_blockEventsOnDrag
; 
 256 //----------------------------------------------------------------------------- 
 257 // define new GTK+ class wxGtkTreeModel 
 258 //----------------------------------------------------------------------------- 
 262 #define GTK_TYPE_WX_TREE_MODEL               (gtk_wx_tree_model_get_type ()) 
 263 #define GTK_WX_TREE_MODEL(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModel)) 
 264 #define GTK_WX_TREE_MODEL_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModelClass)) 
 265 #define GTK_IS_WX_TREE_MODEL(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_TREE_MODEL)) 
 266 #define GTK_IS_WX_TREE_MODEL_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_TREE_MODEL)) 
 267 #define GTK_WX_TREE_MODEL_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModelClass)) 
 269 GType         
gtk_wx_tree_model_get_type         (void); 
 271 typedef struct _GtkWxTreeModelClass  GtkWxTreeModelClass
; 
 273 struct _GtkWxTreeModel
 
 279   wxDataViewCtrlInternal 
*internal
; 
 282 struct _GtkWxTreeModelClass
 
 284   GObjectClass list_parent_class
; 
 287 static GtkWxTreeModel 
*wxgtk_tree_model_new          (void); 
 288 static void         wxgtk_tree_model_init            (GtkWxTreeModel       
*tree_model
); 
 289 static void         wxgtk_tree_model_class_init      (GtkWxTreeModelClass  
*klass
); 
 291 static void         wxgtk_tree_model_tree_model_init (GtkTreeModelIface       
*iface
); 
 292 static void         wxgtk_tree_model_sortable_init   (GtkTreeSortableIface    
*iface
); 
 293 static void         wxgtk_tree_model_drag_source_init(GtkTreeDragSourceIface  
*iface
); 
 294 static void         wxgtk_tree_model_drag_dest_init  (GtkTreeDragDestIface    
*iface
); 
 296 static void         wxgtk_tree_model_finalize        (GObject           
*object
); 
 297 static GtkTreeModelFlags 
wxgtk_tree_model_get_flags  (GtkTreeModel      
*tree_model
); 
 298 static gint         
wxgtk_tree_model_get_n_columns   (GtkTreeModel      
*tree_model
); 
 299 static GType        
wxgtk_tree_model_get_column_type (GtkTreeModel      
*tree_model
, 
 301 static gboolean     
wxgtk_tree_model_get_iter        (GtkTreeModel      
*tree_model
, 
 304 static GtkTreePath 
*wxgtk_tree_model_get_path        (GtkTreeModel      
*tree_model
, 
 306 static void         wxgtk_tree_model_get_value       (GtkTreeModel      
*tree_model
, 
 310 static gboolean     
wxgtk_tree_model_iter_next       (GtkTreeModel      
*tree_model
, 
 312 static gboolean     
wxgtk_tree_model_iter_children   (GtkTreeModel      
*tree_model
, 
 314                                                       GtkTreeIter       
*parent
); 
 315 static gboolean     
wxgtk_tree_model_iter_has_child  (GtkTreeModel      
*tree_model
, 
 317 static gint         
wxgtk_tree_model_iter_n_children (GtkTreeModel      
*tree_model
, 
 319 static gboolean     
wxgtk_tree_model_iter_nth_child  (GtkTreeModel      
*tree_model
, 
 323 static gboolean     
wxgtk_tree_model_iter_parent     (GtkTreeModel      
*tree_model
, 
 328 static gboolean 
wxgtk_tree_model_get_sort_column_id    (GtkTreeSortable       
*sortable
, 
 329                                                         gint                  
*sort_column_id
, 
 331 static void     wxgtk_tree_model_set_sort_column_id    (GtkTreeSortable       
*sortable
, 
 334 static void     wxgtk_tree_model_set_sort_func         (GtkTreeSortable       
*sortable
, 
 336                                                         GtkTreeIterCompareFunc func
, 
 338                                                         GtkDestroyNotify       destroy
); 
 339 static void     wxgtk_tree_model_set_default_sort_func (GtkTreeSortable       
*sortable
, 
 340                                                         GtkTreeIterCompareFunc func
, 
 342                                                         GtkDestroyNotify       destroy
); 
 343 static gboolean 
wxgtk_tree_model_has_default_sort_func (GtkTreeSortable       
*sortable
); 
 346 static gboolean 
wxgtk_tree_model_row_draggable         (GtkTreeDragSource     
*drag_source
, 
 348 static gboolean 
wxgtk_tree_model_drag_data_delete      (GtkTreeDragSource     
*drag_source
, 
 350 static gboolean 
wxgtk_tree_model_drag_data_get         (GtkTreeDragSource     
*drag_source
, 
 352                                                         GtkSelectionData      
*selection_data
); 
 353 static gboolean 
wxgtk_tree_model_drag_data_received    (GtkTreeDragDest       
*drag_dest
, 
 355                                                         GtkSelectionData      
*selection_data
); 
 356 static gboolean 
wxgtk_tree_model_row_drop_possible     (GtkTreeDragDest       
*drag_dest
, 
 357                                                         GtkTreePath           
*dest_path
, 
 358                                                         GtkSelectionData      
*selection_data
); 
 361 static GObjectClass 
*list_parent_class 
= NULL
; 
 364 gtk_wx_tree_model_get_type (void) 
 366     static GType tree_model_type 
= 0; 
 368     if (!tree_model_type
) 
 370         const GTypeInfo tree_model_info 
= 
 372             sizeof (GtkWxTreeModelClass
), 
 373             NULL
,   /* base_init */ 
 374             NULL
,   /* base_finalize */ 
 375             (GClassInitFunc
) wxgtk_tree_model_class_init
, 
 376             NULL
,   /* class_finalize */ 
 377             NULL
,   /* class_data */ 
 378             sizeof (GtkWxTreeModel
), 
 380             (GInstanceInitFunc
) wxgtk_tree_model_init
, 
 383         static const GInterfaceInfo tree_model_iface_info 
= 
 385             (GInterfaceInitFunc
) wxgtk_tree_model_tree_model_init
, 
 390         static const GInterfaceInfo sortable_iface_info 
= 
 392             (GInterfaceInitFunc
) wxgtk_tree_model_sortable_init
, 
 397         static const GInterfaceInfo drag_source_iface_info 
= 
 399             (GInterfaceInitFunc
) wxgtk_tree_model_drag_source_init
, 
 404         static const GInterfaceInfo drag_dest_iface_info 
= 
 406             (GInterfaceInitFunc
) wxgtk_tree_model_drag_dest_init
, 
 411         tree_model_type 
= g_type_register_static (G_TYPE_OBJECT
, "GtkWxTreeModel", 
 412                                                 &tree_model_info
, (GTypeFlags
)0 ); 
 414         g_type_add_interface_static (tree_model_type
, 
 416                                      &tree_model_iface_info
); 
 417         g_type_add_interface_static (tree_model_type
, 
 418                                      GTK_TYPE_TREE_SORTABLE
, 
 419                                      &sortable_iface_info
); 
 420         g_type_add_interface_static (tree_model_type
, 
 421                                      GTK_TYPE_TREE_DRAG_DEST
, 
 422                                      &drag_dest_iface_info
); 
 423         g_type_add_interface_static (tree_model_type
, 
 424                                      GTK_TYPE_TREE_DRAG_SOURCE
, 
 425                                      &drag_source_iface_info
); 
 428     return tree_model_type
; 
 431 static GtkWxTreeModel 
* 
 432 wxgtk_tree_model_new(void) 
 434     GtkWxTreeModel 
*retval 
= (GtkWxTreeModel 
*) g_object_new (GTK_TYPE_WX_TREE_MODEL
, NULL
); 
 439 wxgtk_tree_model_class_init (GtkWxTreeModelClass 
*klass
) 
 441     list_parent_class 
= (GObjectClass
*) g_type_class_peek_parent (klass
); 
 442     GObjectClass 
*object_class 
= (GObjectClass
*) klass
; 
 443     object_class
->finalize 
= wxgtk_tree_model_finalize
; 
 447 wxgtk_tree_model_tree_model_init (GtkTreeModelIface 
*iface
) 
 449     iface
->get_flags 
= wxgtk_tree_model_get_flags
; 
 450     iface
->get_n_columns 
= wxgtk_tree_model_get_n_columns
; 
 451     iface
->get_column_type 
= wxgtk_tree_model_get_column_type
; 
 452     iface
->get_iter 
= wxgtk_tree_model_get_iter
; 
 453     iface
->get_path 
= wxgtk_tree_model_get_path
; 
 454     iface
->get_value 
= wxgtk_tree_model_get_value
; 
 455     iface
->iter_next 
= wxgtk_tree_model_iter_next
; 
 456     iface
->iter_children 
= wxgtk_tree_model_iter_children
; 
 457     iface
->iter_has_child 
= wxgtk_tree_model_iter_has_child
; 
 458     iface
->iter_n_children 
= wxgtk_tree_model_iter_n_children
; 
 459     iface
->iter_nth_child 
= wxgtk_tree_model_iter_nth_child
; 
 460     iface
->iter_parent 
= wxgtk_tree_model_iter_parent
; 
 464 wxgtk_tree_model_sortable_init (GtkTreeSortableIface 
*iface
) 
 466     iface
->get_sort_column_id 
= wxgtk_tree_model_get_sort_column_id
; 
 467     iface
->set_sort_column_id 
= wxgtk_tree_model_set_sort_column_id
; 
 468     iface
->set_sort_func 
= wxgtk_tree_model_set_sort_func
; 
 469     iface
->set_default_sort_func 
= wxgtk_tree_model_set_default_sort_func
; 
 470     iface
->has_default_sort_func 
= wxgtk_tree_model_has_default_sort_func
; 
 474 wxgtk_tree_model_drag_source_init(GtkTreeDragSourceIface  
*iface
) 
 476     iface
->row_draggable 
= wxgtk_tree_model_row_draggable
; 
 477     iface
->drag_data_delete 
= wxgtk_tree_model_drag_data_delete
; 
 478     iface
->drag_data_get 
= wxgtk_tree_model_drag_data_get
; 
 482 wxgtk_tree_model_drag_dest_init  (GtkTreeDragDestIface    
*iface
) 
 484     iface
->drag_data_received 
= wxgtk_tree_model_drag_data_received
; 
 485     iface
->row_drop_possible 
= wxgtk_tree_model_row_drop_possible
; 
 489 wxgtk_tree_model_init (GtkWxTreeModel 
*tree_model
) 
 491     tree_model
->internal 
= NULL
; 
 492     tree_model
->stamp 
= g_random_int(); 
 496 wxgtk_tree_model_finalize (GObject 
*object
) 
 499     (* list_parent_class
->finalize
) (object
); 
 504 //----------------------------------------------------------------------------- 
 505 // implement callbacks from wxGtkTreeModel class by letting 
 506 // them call the methods of wxWidgets' wxDataViewModel 
 507 //----------------------------------------------------------------------------- 
 509 static GtkTreeModelFlags
 
 510 wxgtk_tree_model_get_flags (GtkTreeModel 
*tree_model
) 
 512     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 513     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), (GtkTreeModelFlags
)0 ); 
 515     return wxtree_model
->internal
->get_flags(); 
 519 wxgtk_tree_model_get_n_columns (GtkTreeModel 
*tree_model
) 
 521     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 522     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), 0); 
 524     return wxtree_model
->internal
->GetDataViewModel()->GetColumnCount(); 
 528 wxgtk_tree_model_get_column_type (GtkTreeModel 
*tree_model
, 
 531     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 532     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), G_TYPE_INVALID
); 
 534     GType gtype 
= G_TYPE_INVALID
; 
 536     wxString wxtype 
= wxtree_model
->internal
->GetDataViewModel()->GetColumnType( (unsigned int) index 
); 
 538     if (wxtype 
== wxT("string")) 
 539         gtype 
= G_TYPE_STRING
; 
 542         gtype 
= G_TYPE_STRING
; 
 543         // wxFAIL_MSG( wxT("non-string columns not supported yet") ); 
 550 wxgtk_tree_model_get_iter (GtkTreeModel 
*tree_model
, 
 554     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 555     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 556     g_return_val_if_fail (gtk_tree_path_get_depth (path
) > 0, FALSE
); 
 558     return wxtree_model
->internal
->get_iter( iter
, path 
); 
 562 wxgtk_tree_model_get_path (GtkTreeModel 
*tree_model
, 
 565     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 566     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), NULL
); 
 567     g_return_val_if_fail (iter
->stamp 
== GTK_WX_TREE_MODEL (wxtree_model
)->stamp
, NULL
); 
 569     return wxtree_model
->internal
->get_path( iter 
); 
 573 wxgtk_tree_model_get_value (GtkTreeModel 
*tree_model
, 
 578     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 579     g_return_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
) ); 
 581     wxDataViewModel 
*model 
= wxtree_model
->internal
->GetDataViewModel(); 
 582     wxString mtype 
= model
->GetColumnType( (unsigned int) column 
); 
 583     if (mtype 
== wxT("string")) 
 586         g_value_init( value
, G_TYPE_STRING 
); 
 587         wxDataViewItem 
item( (void*) iter
->user_data 
); 
 588         model
->GetValue( variant
, item
, (unsigned int) column 
); 
 590         g_value_set_string( value
, variant
.GetString().utf8_str() ); 
 594         wxFAIL_MSG( wxT("non-string columns not supported yet") ); 
 599 wxgtk_tree_model_iter_next (GtkTreeModel  
*tree_model
, 
 602     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 604     // This happens when clearing the view by calling .._set_model( NULL ); 
 605     if (iter
->stamp 
== 0) return FALSE
; 
 607     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 608     g_return_val_if_fail (wxtree_model
->stamp 
== iter
->stamp
, FALSE
); 
 610     return wxtree_model
->internal
->iter_next( iter 
); 
 614 wxgtk_tree_model_iter_children (GtkTreeModel 
*tree_model
, 
 618     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 619     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 620     g_return_val_if_fail (wxtree_model
->stamp 
== parent
->stamp
, FALSE
); 
 622     return wxtree_model
->internal
->iter_children( iter
, parent 
); 
 626 wxgtk_tree_model_iter_has_child (GtkTreeModel 
*tree_model
, 
 629     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 630     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 631     g_return_val_if_fail (wxtree_model
->stamp 
== iter
->stamp
, FALSE
); 
 633     return wxtree_model
->internal
->iter_has_child( iter 
); 
 637 wxgtk_tree_model_iter_n_children (GtkTreeModel 
*tree_model
, 
 640     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 641     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), 0); 
 642     g_return_val_if_fail ( !iter 
|| wxtree_model
->stamp 
== iter
->stamp
, 0); 
 644     return wxtree_model
->internal
->iter_n_children( iter 
); 
 648 wxgtk_tree_model_iter_nth_child (GtkTreeModel 
*tree_model
, 
 653     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 654     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 656     return wxtree_model
->internal
->iter_nth_child( iter
, parent
, n 
); 
 660 wxgtk_tree_model_iter_parent (GtkTreeModel 
*tree_model
, 
 664     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 665     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 666     g_return_val_if_fail (wxtree_model
->stamp 
== child
->stamp
, FALSE
); 
 668     return wxtree_model
->internal
->iter_parent( iter
, child 
); 
 671 /* drag'n'drop iface */ 
 673 wxgtk_tree_model_row_draggable (GtkTreeDragSource 
*drag_source
, 
 676     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) drag_source
; 
 677     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 679     return wxtree_model
->internal
->row_draggable( drag_source
, path 
); 
 683 wxgtk_tree_model_drag_data_delete (GtkTreeDragSource 
*drag_source
, 
 686     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) drag_source
; 
 687     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 689     return wxtree_model
->internal
->drag_data_delete( drag_source
, path 
); 
 693 wxgtk_tree_model_drag_data_get (GtkTreeDragSource 
*drag_source
, 
 695                                 GtkSelectionData  
*selection_data
) 
 697     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) drag_source
; 
 698     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 701     wxPrintf( "drag_get_data\n"); 
 703     wxGtkString 
atom_selection(gdk_atom_name(selection_data
->selection
)); 
 704     wxPrintf( "selection %s\n", wxString::FromAscii(atom_selection
) ); 
 706     wxGtkString 
atom_target(gdk_atom_name(selection_data
->target
)); 
 707     wxPrintf( "target %s\n", wxString::FromAscii(atom_target
) ); 
 709     wxGtkString 
atom_type(gdk_atom_name(selection_data
->type
)); 
 710     wxPrintf( "type %s\n", wxString::FromAscii(atom_type
) ); 
 712     wxPrintf( "format %d\n", selection_data
->format 
); 
 715     return wxtree_model
->internal
->drag_data_get( drag_source
, path
, selection_data 
); 
 719 wxgtk_tree_model_drag_data_received (GtkTreeDragDest  
*drag_dest
, 
 721                                      GtkSelectionData 
*selection_data
) 
 723     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) drag_dest
; 
 724     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 726     return wxtree_model
->internal
->drag_data_received( drag_dest
, dest
, selection_data 
); 
 730 wxgtk_tree_model_row_drop_possible (GtkTreeDragDest  
*drag_dest
, 
 731                                     GtkTreePath      
*dest_path
, 
 732                                     GtkSelectionData 
*selection_data
) 
 734     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) drag_dest
; 
 735     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 737     return wxtree_model
->internal
->row_drop_possible( drag_dest
, dest_path
, selection_data 
); 
 742 wxgtk_tree_model_get_sort_column_id (GtkTreeSortable 
*sortable
, 
 743                                      gint            
*sort_column_id
, 
 746     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) sortable
; 
 748     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (sortable
), FALSE
); 
 750     if (!wxtree_model
->internal
->IsSorted()) 
 753             *sort_column_id 
= -1; 
 760         *sort_column_id 
= wxtree_model
->internal
->GetSortColumn(); 
 763         *order 
= wxtree_model
->internal
->GetSortOrder(); 
 768 wxDataViewColumn 
*gs_lastLeftClickHeader 
= NULL
; 
 771 wxgtk_tree_model_set_sort_column_id (GtkTreeSortable 
*sortable
, 
 775     GtkWxTreeModel 
*tree_model 
= (GtkWxTreeModel 
*) sortable
; 
 776     g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable
) ); 
 778     tree_model
->internal
->SetDataViewSortColumn( gs_lastLeftClickHeader 
); 
 780     if ((sort_column_id 
!= (gint
) tree_model
->internal
->GetSortColumn()) || 
 781         (order 
!= tree_model
->internal
->GetSortOrder())) 
 783         tree_model
->internal
->SetSortColumn( sort_column_id 
); 
 784         tree_model
->internal
->SetSortOrder( order 
); 
 786         gtk_tree_sortable_sort_column_changed (sortable
); 
 788         tree_model
->internal
->GetDataViewModel()->Resort(); 
 791     if (gs_lastLeftClickHeader
) 
 793         wxDataViewCtrl 
*dv 
= tree_model
->internal
->GetOwner(); 
 794         wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED
, dv
->GetId() ); 
 795         event
.SetDataViewColumn( gs_lastLeftClickHeader 
); 
 796         event
.SetModel( dv
->GetModel() ); 
 797         dv
->HandleWindowEvent( event 
); 
 800     gs_lastLeftClickHeader 
= NULL
; 
 804 wxgtk_tree_model_set_sort_func (GtkTreeSortable        
*sortable
, 
 805                                 gint                    
WXUNUSED(sort_column_id
), 
 806                                 GtkTreeIterCompareFunc  func
, 
 807                                 gpointer                
WXUNUSED(data
), 
 808                                 GtkDestroyNotify        
WXUNUSED(destroy
)) 
 810     g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable
) ); 
 811     g_return_if_fail (func 
!= NULL
); 
 815 wxgtk_tree_model_set_default_sort_func (GtkTreeSortable          
*sortable
, 
 816                                         GtkTreeIterCompareFunc    func
, 
 817                                         gpointer                  
WXUNUSED(data
), 
 818                                         GtkDestroyNotify          
WXUNUSED(destroy
)) 
 820     g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable
) ); 
 821     g_return_if_fail (func 
!= NULL
); 
 823     //wxPrintf( "wxgtk_tree_model_set_default_sort_func\n" ); 
 824     // TODO: remove this code 
 828 wxgtk_tree_model_has_default_sort_func (GtkTreeSortable        
*sortable
) 
 830     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (sortable
), FALSE 
); 
 835 //----------------------------------------------------------------------------- 
 836 // define new GTK+ class GtkWxRendererText 
 837 //----------------------------------------------------------------------------- 
 841 #define GTK_TYPE_WX_CELL_RENDERER_TEXT               (gtk_wx_cell_renderer_text_get_type ()) 
 842 #define GTK_WX_CELL_RENDERER_TEXT(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_CELL_RENDERER_TEXT, GtkWxCellRendererText)) 
 843 #define GTK_WX_CELL_RENDERER_TEXT_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_CELL_RENDERER_TEXT, GtkWxCellRendererTextClass)) 
 844 #define GTK_IS_WX_CELL_RENDERER_TEXT(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_CELL_RENDERER_TEXT)) 
 845 #define GTK_IS_WX_CELL_RENDERER_TEXT_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_CELL_RENDERER_TEXT)) 
 846 #define GTK_WX_CELL_RENDERER_TEXT_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_CELL_RENDERER_TEXT, GtkWxCellRendererTextClass)) 
 848 GType            
gtk_wx_cell_renderer_text_get_type (void); 
 850 typedef struct _GtkWxCellRendererText GtkWxCellRendererText
; 
 851 typedef struct _GtkWxCellRendererTextClass GtkWxCellRendererTextClass
; 
 853 struct _GtkWxCellRendererText
 
 855   GtkCellRendererText parent
; 
 857   wxDataViewRenderer 
*wx_renderer
; 
 860 struct _GtkWxCellRendererTextClass
 
 862   GtkCellRendererTextClass cell_parent_class
; 
 866 static GtkWxCellRendererText 
*gtk_wx_cell_renderer_text_new   (void); 
 867 static void gtk_wx_cell_renderer_text_init ( 
 868                         GtkWxCellRendererText      
*cell 
); 
 869 static void gtk_wx_cell_renderer_text_class_init( 
 870                         GtkWxCellRendererTextClass 
*klass 
); 
 871 static void gtk_wx_cell_renderer_text_finalize ( 
 873 static GtkCellEditable 
*gtk_wx_cell_renderer_text_start_editing( 
 874                         GtkCellRenderer         
*cell
, 
 878                         GdkRectangle            
*background_area
, 
 879                         GdkRectangle            
*cell_area
, 
 880                         GtkCellRendererState     flags 
); 
 883 static GObjectClass 
*text_cell_parent_class 
= NULL
; 
 888 gtk_wx_cell_renderer_text_get_type (void) 
 890     static GType cell_wx_type 
= 0; 
 894         const GTypeInfo cell_wx_info 
= 
 896             sizeof (GtkWxCellRendererTextClass
), 
 897             NULL
, /* base_init */ 
 898             NULL
, /* base_finalize */ 
 899             (GClassInitFunc
) gtk_wx_cell_renderer_text_class_init
, 
 900             NULL
, /* class_finalize */ 
 901             NULL
, /* class_data */ 
 902             sizeof (GtkWxCellRendererText
), 
 904             (GInstanceInitFunc
) gtk_wx_cell_renderer_text_init
, 
 907         cell_wx_type 
= g_type_register_static( GTK_TYPE_CELL_RENDERER_TEXT
, 
 908             "GtkWxCellRendererText", &cell_wx_info
, (GTypeFlags
)0 ); 
 915 gtk_wx_cell_renderer_text_init (GtkWxCellRendererText 
*cell
) 
 917     cell
->wx_renderer 
= NULL
; 
 921 gtk_wx_cell_renderer_text_class_init (GtkWxCellRendererTextClass 
*klass
) 
 923     GObjectClass 
*object_class 
= G_OBJECT_CLASS (klass
); 
 924     GtkCellRendererClass 
*cell_class 
= GTK_CELL_RENDERER_CLASS (klass
); 
 926     text_cell_parent_class 
= (GObjectClass
*) g_type_class_peek_parent (klass
); 
 928     object_class
->finalize 
= gtk_wx_cell_renderer_text_finalize
; 
 930     cell_class
->start_editing 
= gtk_wx_cell_renderer_text_start_editing
; 
 934 gtk_wx_cell_renderer_text_finalize (GObject 
*object
) 
 937     (* G_OBJECT_CLASS (text_cell_parent_class
)->finalize
) (object
); 
 940 GtkWxCellRendererText
* 
 941 gtk_wx_cell_renderer_text_new (void) 
 943     return (GtkWxCellRendererText
*) g_object_new (GTK_TYPE_WX_CELL_RENDERER_TEXT
, NULL
); 
 946 static GtkCellEditable 
*gtk_wx_cell_renderer_text_start_editing( 
 947                         GtkCellRenderer         
*gtk_renderer
, 
 951                         GdkRectangle            
*background_area
, 
 952                         GdkRectangle            
*cell_area
, 
 953                         GtkCellRendererState     flags 
) 
 955     GtkWxCellRendererText 
*wxgtk_renderer 
= (GtkWxCellRendererText 
*) gtk_renderer
; 
 956     wxDataViewRenderer 
*wx_renderer 
= wxgtk_renderer
->wx_renderer
; 
 958     GtkTreePath 
*treepath 
= gtk_tree_path_new_from_string( path 
); 
 960     wx_renderer
->GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter
, treepath 
); 
 961     wxDataViewItem 
item( (void*) iter
.user_data 
);; 
 962     gtk_tree_path_free( treepath 
); 
 964     wxDataViewColumn 
*column 
= wx_renderer
->GetOwner(); 
 965     wxDataViewCtrl 
*dv 
= column
->GetOwner(); 
 966     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_START_EDITING
, dv
->GetId() ); 
 967     event
.SetDataViewColumn( column 
); 
 968     event
.SetModel( dv
->GetModel() ); 
 969     event
.SetColumn( wx_renderer
->GetOwner()->GetModelColumn() ); 
 970     event
.SetItem( item 
); 
 971     dv
->HandleWindowEvent( event 
); 
 973     if (event
.IsAllowed()) 
 974         return GTK_CELL_RENDERER_CLASS(text_cell_parent_class
)-> 
 975            start_editing( gtk_renderer
, gdk_event
, widget
, path
, background_area
, cell_area
, flags 
); 
 980 //----------------------------------------------------------------------------- 
 981 // define new GTK+ class GtkWxCellRenderer 
 982 //----------------------------------------------------------------------------- 
 986 #define GTK_TYPE_WX_CELL_RENDERER               (gtk_wx_cell_renderer_get_type ()) 
 987 #define GTK_WX_CELL_RENDERER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRenderer)) 
 988 #define GTK_WX_CELL_RENDERER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRendererClass)) 
 989 #define GTK_IS_WX_CELL_RENDERER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_CELL_RENDERER)) 
 990 #define GTK_IS_WX_CELL_RENDERER_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_CELL_RENDERER)) 
 991 #define GTK_WX_CELL_RENDERER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRendererClass)) 
 993 GType            
gtk_wx_cell_renderer_get_type (void); 
 995 typedef struct _GtkWxCellRenderer GtkWxCellRenderer
; 
 996 typedef struct _GtkWxCellRendererClass GtkWxCellRendererClass
; 
 998 struct _GtkWxCellRenderer
 
1000   GtkCellRenderer parent
; 
1003   wxDataViewCustomRenderer 
*cell
; 
1007 struct _GtkWxCellRendererClass
 
1009   GtkCellRendererClass cell_parent_class
; 
1013 static GtkCellRenderer 
*gtk_wx_cell_renderer_new   (void); 
1014 static void gtk_wx_cell_renderer_init ( 
1015                         GtkWxCellRenderer      
*cell 
); 
1016 static void gtk_wx_cell_renderer_class_init( 
1017                         GtkWxCellRendererClass 
*klass 
); 
1018 static void gtk_wx_cell_renderer_finalize ( 
1020 static void gtk_wx_cell_renderer_get_size ( 
1021                         GtkCellRenderer         
*cell
, 
1023                         GdkRectangle            
*rectangle
, 
1028 static void gtk_wx_cell_renderer_render ( 
1029                         GtkCellRenderer         
*cell
, 
1032                         GdkRectangle            
*background_area
, 
1033                         GdkRectangle            
*cell_area
, 
1034                         GdkRectangle            
*expose_area
, 
1035                         GtkCellRendererState     flags 
); 
1036 static gboolean 
gtk_wx_cell_renderer_activate( 
1037                         GtkCellRenderer         
*cell
, 
1041                         GdkRectangle            
*background_area
, 
1042                         GdkRectangle            
*cell_area
, 
1043                         GtkCellRendererState     flags 
); 
1044 static GtkCellEditable 
*gtk_wx_cell_renderer_start_editing( 
1045                         GtkCellRenderer         
*cell
, 
1049                         GdkRectangle            
*background_area
, 
1050                         GdkRectangle            
*cell_area
, 
1051                         GtkCellRendererState     flags 
); 
1054 static GObjectClass 
*cell_parent_class 
= NULL
; 
1059 gtk_wx_cell_renderer_get_type (void) 
1061     static GType cell_wx_type 
= 0; 
1065         const GTypeInfo cell_wx_info 
= 
1067             sizeof (GtkWxCellRendererClass
), 
1068             NULL
, /* base_init */ 
1069             NULL
, /* base_finalize */ 
1070             (GClassInitFunc
) gtk_wx_cell_renderer_class_init
, 
1071             NULL
, /* class_finalize */ 
1072             NULL
, /* class_data */ 
1073             sizeof (GtkWxCellRenderer
), 
1074             0,          /* n_preallocs */ 
1075             (GInstanceInitFunc
) gtk_wx_cell_renderer_init
, 
1078         cell_wx_type 
= g_type_register_static( GTK_TYPE_CELL_RENDERER
, 
1079             "GtkWxCellRenderer", &cell_wx_info
, (GTypeFlags
)0 ); 
1082     return cell_wx_type
; 
1086 gtk_wx_cell_renderer_init (GtkWxCellRenderer 
*cell
) 
1089     cell
->last_click 
= 0; 
1093 gtk_wx_cell_renderer_class_init (GtkWxCellRendererClass 
*klass
) 
1095     GObjectClass 
*object_class 
= G_OBJECT_CLASS (klass
); 
1096     GtkCellRendererClass 
*cell_class 
= GTK_CELL_RENDERER_CLASS (klass
); 
1098     cell_parent_class 
= (GObjectClass
*) g_type_class_peek_parent (klass
); 
1100     object_class
->finalize 
= gtk_wx_cell_renderer_finalize
; 
1102     cell_class
->get_size 
= gtk_wx_cell_renderer_get_size
; 
1103     cell_class
->render 
= gtk_wx_cell_renderer_render
; 
1104     cell_class
->activate 
= gtk_wx_cell_renderer_activate
; 
1105     cell_class
->start_editing 
= gtk_wx_cell_renderer_start_editing
; 
1109 gtk_wx_cell_renderer_finalize (GObject 
*object
) 
1112     (* G_OBJECT_CLASS (cell_parent_class
)->finalize
) (object
); 
1116 gtk_wx_cell_renderer_new (void) 
1118     return (GtkCellRenderer
*) g_object_new (GTK_TYPE_WX_CELL_RENDERER
, NULL
); 
1121 static GtkCellEditable 
*gtk_wx_cell_renderer_start_editing( 
1122                         GtkCellRenderer         
*renderer
, 
1123                         GdkEvent                
*WXUNUSED(event
), 
1126                         GdkRectangle            
*WXUNUSED(background_area
), 
1127                         GdkRectangle            
*cell_area
, 
1128                         GtkCellRendererState     
WXUNUSED(flags
) ) 
1130     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
1131     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
1133     // Renderer doesn't support in-place editing 
1134     if (!cell
->HasEditorCtrl()) 
1137     // An in-place editing control is still around 
1138     if (cell
->GetEditorCtrl()) 
1142     gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
, 
1148     rect
.x 
+= cell_area
->x
; 
1149     rect
.y 
+= cell_area
->y
; 
1150 //    rect.width  -= renderer->xpad * 2; 
1151 //    rect.height -= renderer->ypad * 2; 
1153 //    wxRect renderrect( rect.x, rect.y, rect.width, rect.height ); 
1154     wxRect 
renderrect( cell_area
->x
, cell_area
->y
, cell_area
->width
, cell_area
->height 
); 
1156     GtkTreePath 
*treepath 
= gtk_tree_path_new_from_string( path 
); 
1158     cell
->GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter
, treepath 
); 
1159     wxDataViewItem 
item( (void*) iter
.user_data 
); 
1160     gtk_tree_path_free( treepath 
); 
1162     cell
->StartEditing( item
, renderrect 
); 
1168 gtk_wx_cell_renderer_get_size (GtkCellRenderer 
*renderer
, 
1169                                GtkWidget       
*WXUNUSED(widget
), 
1170                                GdkRectangle    
*cell_area
, 
1176     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
1177     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
1179     wxSize size 
= cell
->GetSize(); 
1181     gint calc_width  
= (gint
) renderer
->xpad 
* 2 + size
.x
; 
1182     gint calc_height 
= (gint
) renderer
->ypad 
* 2 + size
.y
; 
1189     if (cell_area 
&& size
.x 
> 0 && size
.y 
> 0) 
1193             *x_offset 
= (gint
)((renderer
->xalign 
* 
1194                                (cell_area
->width 
- calc_width 
- 2 * renderer
->xpad
))); 
1195             *x_offset 
= MAX (*x_offset
, 0) + renderer
->xpad
; 
1199             *y_offset 
= (gint
)((renderer
->yalign 
* 
1200                                (cell_area
->height 
- calc_height 
- 2 * renderer
->ypad
))); 
1201             *y_offset 
= MAX (*y_offset
, 0) + renderer
->ypad
; 
1206         *width 
= calc_width
; 
1209         *height 
= calc_height
; 
1213 gtk_wx_cell_renderer_render (GtkCellRenderer      
*renderer
, 
1216                              GdkRectangle         
*background_area
, 
1217                              GdkRectangle         
*cell_area
, 
1218                              GdkRectangle         
*expose_area
, 
1219                              GtkCellRendererState  flags
) 
1222     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
1223     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
1225     cell
->window 
= window
; 
1226     cell
->widget 
= widget
; 
1227     cell
->background_area 
= (void*) background_area
; 
1228     cell
->cell_area 
= (void*) cell_area
; 
1229     cell
->expose_area 
= (void*) expose_area
; 
1230     cell
->flags 
= (int) flags
; 
1233     gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
, 
1239     rect
.x 
+= cell_area
->x
; 
1240     rect
.y 
+= cell_area
->y
; 
1241     rect
.width  
-= renderer
->xpad 
* 2; 
1242     rect
.height 
-= renderer
->ypad 
* 2; 
1245     if (gdk_rectangle_intersect (expose_area
, &rect
, &dummy
)) 
1247         wxRect 
renderrect( rect
.x
, rect
.y
, rect
.width
, rect
.height 
); 
1248         wxWindowDC
* dc 
= (wxWindowDC
*) cell
->GetDC(); 
1249         wxWindowDCImpl 
*impl 
= (wxWindowDCImpl 
*) dc
->GetImpl(); 
1251         // Reinitialize wxWindowDC's GDK window if drawing occurs into a different 
1252         // window such as a DnD drop window. 
1253         if (window 
!= impl
->m_gdkwindow
) 
1256             impl
->m_gdkwindow 
= window
; 
1261         if (flags 
& GTK_CELL_RENDERER_SELECTED
) 
1262             state 
|= wxDATAVIEW_CELL_SELECTED
; 
1263         if (flags 
& GTK_CELL_RENDERER_PRELIT
) 
1264             state 
|= wxDATAVIEW_CELL_PRELIT
; 
1265         if (flags 
& GTK_CELL_RENDERER_INSENSITIVE
) 
1266             state 
|= wxDATAVIEW_CELL_INSENSITIVE
; 
1267         if (flags 
& GTK_CELL_RENDERER_INSENSITIVE
) 
1268             state 
|= wxDATAVIEW_CELL_INSENSITIVE
; 
1269         if (flags 
& GTK_CELL_RENDERER_FOCUSED
) 
1270             state 
|= wxDATAVIEW_CELL_FOCUSED
; 
1271         cell
->Render( renderrect
, dc
, state 
); 
1276 gtk_wx_cell_renderer_activate( 
1277                         GtkCellRenderer         
*renderer
, 
1281                         GdkRectangle            
*WXUNUSED(background_area
), 
1282                         GdkRectangle            
*cell_area
, 
1283                         GtkCellRendererState     
WXUNUSED(flags
) ) 
1285     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
1286     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
1289     gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
, 
1295     rect
.x 
+= cell_area
->x
; 
1296     rect
.y 
+= cell_area
->y
; 
1297     rect
.width  
-= renderer
->xpad 
* 2; 
1298     rect
.height 
-= renderer
->ypad 
* 2; 
1300     wxRect 
renderrect( rect
.x
, rect
.y
, rect
.width
, rect
.height 
); 
1302     wxDataViewModel 
*model 
= cell
->GetOwner()->GetOwner()->GetModel(); 
1304     GtkTreePath 
*treepath 
= gtk_tree_path_new_from_string( path 
); 
1307     cell
->GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter
, treepath 
); 
1308     wxDataViewItem 
item( iter
.user_data 
); 
1309     gtk_tree_path_free( treepath 
); 
1311     unsigned int model_col 
= cell
->GetOwner()->GetModelColumn(); 
1317         // activated by <ENTER> 
1318         if (cell
->Activate( renderrect
, model
, item
, model_col 
)) 
1323     else if (event
->type 
== GDK_BUTTON_PRESS
) 
1325         GdkEventButton 
*button_event 
= (GdkEventButton
*) event
; 
1326         wxPoint 
pt( ((int) button_event
->x
) - renderrect
.x
, 
1327                     ((int) button_event
->y
) - renderrect
.y 
); 
1330         if (button_event
->button 
== 1) 
1332             if (cell
->LeftClick( pt
, renderrect
, model
, item
, model_col 
)) 
1334             // TODO: query system double-click time 
1335             if (button_event
->time 
- wxrenderer
->last_click 
< 400) 
1336                 if (cell
->Activate( renderrect
, model
, item
, model_col 
)) 
1339         wxrenderer
->last_click 
= button_event
->time
; 
1347 // --------------------------------------------------------- 
1348 // wxGtkDataViewModelNotifier 
1349 // --------------------------------------------------------- 
1351 class wxGtkDataViewModelNotifier
: public wxDataViewModelNotifier
 
1354     wxGtkDataViewModelNotifier( GtkWxTreeModel  
*wxgtk_model
, 
1355                                 wxDataViewModel 
*wx_model
, 
1356                                 wxDataViewCtrl  
*ctrl 
); 
1357     ~wxGtkDataViewModelNotifier(); 
1359     virtual bool ItemAdded( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
); 
1360     virtual bool ItemDeleted( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
); 
1361     virtual bool ItemChanged( const wxDataViewItem 
&item 
); 
1362     virtual bool ValueChanged( const wxDataViewItem 
&item
, unsigned int col 
); 
1363     virtual bool Cleared(); 
1364     virtual void Resort(); 
1366     void SetGtkModel( GtkWxTreeModel 
*model 
) { m_wxgtk_model 
= model
; } 
1369     GtkWxTreeModel      
*m_wxgtk_model
; 
1370     wxDataViewModel     
*m_wx_model
; 
1371     wxDataViewCtrl      
*m_owner
; 
1374 // --------------------------------------------------------- 
1375 // wxGtkDataViewListModelNotifier 
1376 // --------------------------------------------------------- 
1378 wxGtkDataViewModelNotifier::wxGtkDataViewModelNotifier( 
1379     GtkWxTreeModel
* wxgtk_model
, wxDataViewModel 
*wx_model
, 
1380     wxDataViewCtrl 
*ctrl 
) 
1382     m_wxgtk_model 
= wxgtk_model
; 
1383     m_wx_model 
= wx_model
; 
1387 wxGtkDataViewModelNotifier::~wxGtkDataViewModelNotifier() 
1390     m_wxgtk_model 
= NULL
; 
1393 bool wxGtkDataViewModelNotifier::ItemAdded( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
) 
1395     m_owner
->GtkGetInternal()->ItemAdded( parent
, item 
); 
1398     iter
.stamp 
= m_wxgtk_model
->stamp
; 
1399     iter
.user_data 
= (gpointer
) item
.GetID(); 
1401     GtkTreePath 
*path 
= wxgtk_tree_model_get_path( 
1402         GTK_TREE_MODEL(m_wxgtk_model
), &iter 
); 
1403     gtk_tree_model_row_inserted( 
1404         GTK_TREE_MODEL(m_wxgtk_model
), path
, &iter
); 
1405     gtk_tree_path_free (path
); 
1410 bool wxGtkDataViewModelNotifier::ItemDeleted( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
) 
1413     iter
.stamp 
= m_wxgtk_model
->stamp
; 
1414     iter
.user_data 
= (gpointer
) item
.GetID(); 
1416     GtkTreePath 
*path 
= wxgtk_tree_model_get_path( 
1417         GTK_TREE_MODEL(m_wxgtk_model
), &iter 
); 
1418     gtk_tree_model_row_deleted( 
1419         GTK_TREE_MODEL(m_wxgtk_model
), path 
); 
1420     gtk_tree_path_free (path
); 
1422     m_owner
->GtkGetInternal()->ItemDeleted( parent
, item 
); 
1427 void wxGtkDataViewModelNotifier::Resort() 
1429     m_owner
->GtkGetInternal()->Resort(); 
1432 bool wxGtkDataViewModelNotifier::ItemChanged( const wxDataViewItem 
&item 
) 
1435     iter
.stamp 
= m_wxgtk_model
->stamp
; 
1436     iter
.user_data 
= (gpointer
) item
.GetID(); 
1438     GtkTreePath 
*path 
= wxgtk_tree_model_get_path( 
1439         GTK_TREE_MODEL(m_wxgtk_model
), &iter 
); 
1440     gtk_tree_model_row_changed( 
1441         GTK_TREE_MODEL(m_wxgtk_model
), path
, &iter 
); 
1442     gtk_tree_path_free (path
); 
1444     m_owner
->GtkGetInternal()->ItemChanged( item 
); 
1449 bool wxGtkDataViewModelNotifier::ValueChanged( const wxDataViewItem 
&item
, unsigned int model_col 
) 
1451     // This adds GTK+'s missing MVC logic for ValueChanged 
1453     for (index 
= 0; index 
< m_owner
->GetColumnCount(); index
++) 
1455         wxDataViewColumn 
*column 
= m_owner
->GetColumn( index 
); 
1456         if (column
->GetModelColumn() == model_col
) 
1458             GtkTreeView 
*widget 
= GTK_TREE_VIEW(m_owner
->m_treeview
); 
1459             GtkTreeViewColumn 
*gcolumn 
= GTK_TREE_VIEW_COLUMN(column
->GetGtkHandle()); 
1463             iter
.stamp 
= m_wxgtk_model
->stamp
; 
1464             iter
.user_data 
= (gpointer
) item
.GetID(); 
1465             GtkTreePath 
*path 
= wxgtk_tree_model_get_path( 
1466                 GTK_TREE_MODEL(m_wxgtk_model
), &iter 
); 
1467             GdkRectangle cell_area
; 
1468             gtk_tree_view_get_cell_area( widget
, path
, gcolumn
, &cell_area 
); 
1469             gtk_tree_path_free( path 
); 
1471             GtkAdjustment
* hadjust 
= gtk_tree_view_get_hadjustment( widget 
); 
1472             double d 
= gtk_adjustment_get_value( hadjust 
); 
1473             int xdiff 
= (int) d
; 
1475             int ydiff 
= gcolumn
->button
->allocation
.height
; 
1477             gtk_widget_queue_draw_area( GTK_WIDGET(widget
), 
1478                 cell_area
.x 
- xdiff
, ydiff 
+ cell_area
.y
, cell_area
.width
, cell_area
.height 
); 
1480             m_owner
->GtkGetInternal()->ValueChanged( item
, model_col 
); 
1489 bool wxGtkDataViewModelNotifier::Cleared() 
1491     m_owner
->GtkGetInternal()->Cleared(); 
1496 // --------------------------------------------------------- 
1497 // wxDataViewRenderer 
1498 // --------------------------------------------------------- 
1500 static gpointer s_user_data 
= NULL
; 
1503 wxgtk_cell_editable_editing_done( GtkCellEditable 
*WXUNUSED(editable
), 
1504                                   wxDataViewRenderer 
*wxrenderer 
) 
1506     wxDataViewColumn 
*column 
= wxrenderer
->GetOwner(); 
1507     wxDataViewCtrl 
*dv 
= column
->GetOwner(); 
1508     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_DONE
, dv
->GetId() ); 
1509     event
.SetDataViewColumn( column 
); 
1510     event
.SetModel( dv
->GetModel() ); 
1511     wxDataViewItem 
item( s_user_data 
); 
1512     event
.SetItem( item 
); 
1513     dv
->HandleWindowEvent( event 
); 
1517 wxgtk_renderer_editing_started( GtkCellRenderer 
*WXUNUSED(cell
), GtkCellEditable 
*editable
, 
1518                                 gchar 
*path
, wxDataViewRenderer 
*wxrenderer 
) 
1523     wxDataViewColumn 
*column 
= wxrenderer
->GetOwner(); 
1524     wxDataViewCtrl 
*dv 
= column
->GetOwner(); 
1525     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_STARTED
, dv
->GetId() ); 
1526     event
.SetDataViewColumn( column 
); 
1527     event
.SetModel( dv
->GetModel() ); 
1528     GtkTreePath 
*tree_path 
= gtk_tree_path_new_from_string( path 
); 
1530     dv
->GtkGetInternal()->get_iter( &iter
, tree_path 
); 
1531     gtk_tree_path_free( tree_path 
); 
1532     wxDataViewItem 
item( iter
.user_data 
); 
1533     event
.SetItem( item 
); 
1534     dv
->HandleWindowEvent( event 
); 
1536     if (GTK_IS_CELL_EDITABLE(editable
)) 
1538         s_user_data 
= iter
.user_data
; 
1540         g_signal_connect (GTK_CELL_EDITABLE (editable
), "editing_done", 
1541             G_CALLBACK (wxgtk_cell_editable_editing_done
), 
1542             (gpointer
) wxrenderer 
); 
1548 IMPLEMENT_ABSTRACT_CLASS(wxDataViewRenderer
, wxDataViewRendererBase
) 
1550 wxDataViewRenderer::wxDataViewRenderer( const wxString 
&varianttype
, wxDataViewCellMode mode
, 
1552     wxDataViewRendererBase( varianttype
, mode
, align 
) 
1556     // NOTE: SetMode() and SetAlignment() needs to be called in the renderer's ctor, 
1557     //       after the m_renderer pointer has been initialized 
1560 void wxDataViewRenderer::GtkInitHandlers() 
1562     if (!gtk_check_version(2,6,0)) 
1564         g_signal_connect (GTK_CELL_RENDERER(m_renderer
), "editing_started", 
1565             G_CALLBACK (wxgtk_renderer_editing_started
), 
1570 void wxDataViewRenderer::SetMode( wxDataViewCellMode mode 
) 
1572     GtkCellRendererMode gtkMode
; 
1575         case wxDATAVIEW_CELL_INERT
: 
1576             gtkMode 
= GTK_CELL_RENDERER_MODE_INERT
; 
1579         case wxDATAVIEW_CELL_ACTIVATABLE
: 
1580             gtkMode 
= GTK_CELL_RENDERER_MODE_ACTIVATABLE
; 
1583         case wxDATAVIEW_CELL_EDITABLE
: 
1584             gtkMode 
= GTK_CELL_RENDERER_MODE_EDITABLE
; 
1588             wxFAIL_MSG( "unknown wxDataViewCellMode value" ); 
1592     // This value is most often ignored in GtkTreeView 
1593     GValue gvalue 
= { 0, }; 
1594     g_value_init( &gvalue
, gtk_cell_renderer_mode_get_type() ); 
1595     g_value_set_enum( &gvalue
, gtkMode 
); 
1596     g_object_set_property( G_OBJECT(m_renderer
), "mode", &gvalue 
); 
1597     g_value_unset( &gvalue 
); 
1600 wxDataViewCellMode 
wxDataViewRenderer::GetMode() const 
1602     wxDataViewCellMode ret
; 
1605     g_object_get( G_OBJECT(m_renderer
), "mode", &gvalue
, NULL
); 
1607     switch (g_value_get_enum(&gvalue
)) 
1610             wxFAIL_MSG( "unknown GtkCellRendererMode value" ); 
1611             // fall through (we have to return something) 
1613         case GTK_CELL_RENDERER_MODE_INERT
: 
1614             ret 
= wxDATAVIEW_CELL_INERT
; 
1617         case GTK_CELL_RENDERER_MODE_ACTIVATABLE
: 
1618             ret 
= wxDATAVIEW_CELL_ACTIVATABLE
; 
1621         case GTK_CELL_RENDERER_MODE_EDITABLE
: 
1622             ret 
= wxDATAVIEW_CELL_EDITABLE
; 
1626     g_value_unset( &gvalue 
); 
1631 void wxDataViewRenderer::GtkUpdateAlignment() 
1633     int align 
= m_alignment
; 
1635     // query alignment from column ? 
1639         if (GetOwner() == NULL
) 
1642         align 
= GetOwner()->GetAlignment(); 
1643         align 
|= wxALIGN_CENTRE_VERTICAL
; 
1646     // horizontal alignment: 
1648     gfloat xalign 
= 0.0; 
1649     if (align 
& wxALIGN_RIGHT
) 
1651     else if (align 
& wxALIGN_CENTER_HORIZONTAL
) 
1654     GValue gvalue 
= { 0, }; 
1655     g_value_init( &gvalue
, G_TYPE_FLOAT 
); 
1656     g_value_set_float( &gvalue
, xalign 
); 
1657     g_object_set_property( G_OBJECT(m_renderer
), "xalign", &gvalue 
); 
1658     g_value_unset( &gvalue 
); 
1660     // vertical alignment: 
1662     gfloat yalign 
= 0.0; 
1663     if (align 
& wxALIGN_BOTTOM
) 
1665     else if (align 
& wxALIGN_CENTER_VERTICAL
) 
1668     GValue gvalue2 
= { 0, }; 
1669     g_value_init( &gvalue2
, G_TYPE_FLOAT 
); 
1670     g_value_set_float( &gvalue2
, yalign 
); 
1671     g_object_set_property( G_OBJECT(m_renderer
), "yalign", &gvalue2 
); 
1672     g_value_unset( &gvalue2 
); 
1675 void wxDataViewRenderer::SetAlignment( int align 
) 
1677     m_alignment 
= align
; 
1678     GtkUpdateAlignment(); 
1681 int wxDataViewRenderer::GetAlignment() const 
1686 // --------------------------------------------------------- 
1687 // wxDataViewTextRenderer 
1688 // --------------------------------------------------------- 
1691 static void wxGtkTextRendererEditedCallback( GtkCellRendererText 
*renderer
, 
1692     gchar 
*arg1
, gchar 
*arg2
, gpointer user_data 
); 
1695 static void wxGtkTextRendererEditedCallback( GtkCellRendererText 
*WXUNUSED(renderer
), 
1696     gchar 
*arg1
, gchar 
*arg2
, gpointer user_data 
) 
1698     wxDataViewRenderer 
*cell 
= (wxDataViewRenderer
*) user_data
; 
1700     wxString tmp 
= wxGTK_CONV_BACK_FONT(arg2
, cell
->GetOwner()->GetOwner()->GetFont()); 
1701     wxVariant value 
= tmp
; 
1702     if (!cell
->Validate( value 
)) 
1705     wxDataViewModel 
*model 
= cell
->GetOwner()->GetOwner()->GetModel(); 
1707     GtkTreePath 
*path 
= gtk_tree_path_new_from_string( arg1 
); 
1709     cell
->GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter
, path 
); 
1710     wxDataViewItem 
item( (void*) iter
.user_data 
);; 
1711     gtk_tree_path_free( path 
); 
1713     unsigned int model_col 
= cell
->GetOwner()->GetModelColumn(); 
1715     model
->SetValue( value
, item
, model_col 
); 
1716     model
->ValueChanged( item
, model_col 
); 
1719 IMPLEMENT_CLASS(wxDataViewTextRenderer
, wxDataViewRenderer
) 
1721 wxDataViewTextRenderer::wxDataViewTextRenderer( const wxString 
&varianttype
, wxDataViewCellMode mode
, 
1723     wxDataViewRenderer( varianttype
, mode
, align 
) 
1725     GtkWxCellRendererText 
*text_renderer 
= gtk_wx_cell_renderer_text_new(); 
1726     text_renderer
->wx_renderer 
= this; 
1727     m_renderer 
= (GtkCellRenderer
*) text_renderer
; 
1729     if (mode 
& wxDATAVIEW_CELL_EDITABLE
) 
1731         GValue gvalue 
= { 0, }; 
1732         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1733         g_value_set_boolean( &gvalue
, true ); 
1734         g_object_set_property( G_OBJECT(m_renderer
), "editable", &gvalue 
); 
1735         g_value_unset( &gvalue 
); 
1737         g_signal_connect_after( m_renderer
, "edited", G_CALLBACK(wxGtkTextRendererEditedCallback
), this ); 
1743     SetAlignment(align
); 
1746 bool wxDataViewTextRenderer::SetValue( const wxVariant 
&value 
) 
1748     wxString tmp 
= value
; 
1750     GValue gvalue 
= { 0, }; 
1751     g_value_init( &gvalue
, G_TYPE_STRING 
); 
1752     g_value_set_string( &gvalue
, wxGTK_CONV_FONT( tmp
, GetOwner()->GetOwner()->GetFont() ) ); 
1753     g_object_set_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
1754     g_value_unset( &gvalue 
); 
1759 bool wxDataViewTextRenderer::GetValue( wxVariant 
&value 
) const 
1761     GValue gvalue 
= { 0, }; 
1762     g_value_init( &gvalue
, G_TYPE_STRING 
); 
1763     g_object_get_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
1764     wxString tmp 
= wxGTK_CONV_BACK_FONT( g_value_get_string( &gvalue 
), const_cast<wxDataViewTextRenderer
*>(this)->GetOwner()->GetOwner()->GetFont() ); 
1765     g_value_unset( &gvalue 
); 
1772 void wxDataViewTextRenderer::SetAlignment( int align 
) 
1774     wxDataViewRenderer::SetAlignment(align
); 
1776     if (gtk_check_version(2,10,0)) 
1779     // horizontal alignment: 
1780     PangoAlignment pangoAlign 
= PANGO_ALIGN_LEFT
; 
1781     if (align 
& wxALIGN_RIGHT
) 
1782         pangoAlign 
= PANGO_ALIGN_RIGHT
; 
1783     else if (align 
& wxALIGN_CENTER_HORIZONTAL
) 
1784         pangoAlign 
= PANGO_ALIGN_CENTER
; 
1786     GValue gvalue 
= { 0, }; 
1787     g_value_init( &gvalue
, gtk_cell_renderer_mode_get_type() ); 
1788     g_value_set_enum( &gvalue
, pangoAlign 
); 
1789     g_object_set_property( G_OBJECT(m_renderer
), "alignment", &gvalue 
); 
1790     g_value_unset( &gvalue 
); 
1793 // --------------------------------------------------------- 
1794 // wxDataViewBitmapRenderer 
1795 // --------------------------------------------------------- 
1797 IMPLEMENT_CLASS(wxDataViewBitmapRenderer
, wxDataViewRenderer
) 
1799 wxDataViewBitmapRenderer::wxDataViewBitmapRenderer( const wxString 
&varianttype
, wxDataViewCellMode mode
, 
1801     wxDataViewRenderer( varianttype
, mode
, align 
) 
1803     m_renderer 
= (GtkCellRenderer
*) gtk_cell_renderer_pixbuf_new(); 
1806     SetAlignment(align
); 
1809 bool wxDataViewBitmapRenderer::SetValue( const wxVariant 
&value 
) 
1811     if (value
.GetType() == wxT("wxBitmap")) 
1816         // This may create a Pixbuf representation in the 
1817         // wxBitmap object (and it will stay there) 
1818         GdkPixbuf 
*pixbuf 
= bitmap
.GetPixbuf(); 
1820         GValue gvalue 
= { 0, }; 
1821         g_value_init( &gvalue
, G_TYPE_OBJECT 
); 
1822         g_value_set_object( &gvalue
, pixbuf 
); 
1823         g_object_set_property( G_OBJECT(m_renderer
), "pixbuf", &gvalue 
); 
1824         g_value_unset( &gvalue 
); 
1829     if (value
.GetType() == wxT("wxIcon")) 
1834         // This may create a Pixbuf representation in the 
1835         // wxBitmap object (and it will stay there) 
1836         GdkPixbuf 
*pixbuf 
= bitmap
.GetPixbuf(); 
1838         GValue gvalue 
= { 0, }; 
1839         g_value_init( &gvalue
, G_TYPE_OBJECT 
); 
1840         g_value_set_object( &gvalue
, pixbuf 
); 
1841         g_object_set_property( G_OBJECT(m_renderer
), "pixbuf", &gvalue 
); 
1842         g_value_unset( &gvalue 
); 
1850 bool wxDataViewBitmapRenderer::GetValue( wxVariant 
&WXUNUSED(value
) ) const 
1855 // --------------------------------------------------------- 
1856 // wxDataViewToggleRenderer 
1857 // --------------------------------------------------------- 
1860 static void wxGtkToggleRendererToggledCallback( GtkCellRendererToggle 
*renderer
, 
1861     gchar 
*path
, gpointer user_data 
); 
1864 static void wxGtkToggleRendererToggledCallback( GtkCellRendererToggle 
*renderer
, 
1865     gchar 
*path
, gpointer user_data 
) 
1867     wxDataViewToggleRenderer 
*cell 
= (wxDataViewToggleRenderer
*) user_data
; 
1870     GValue gvalue 
= { 0, }; 
1871     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1872     g_object_get_property( G_OBJECT(renderer
), "active", &gvalue 
); 
1873     bool tmp 
= g_value_get_boolean( &gvalue 
); 
1874     g_value_unset( &gvalue 
); 
1878     wxVariant value 
= tmp
; 
1879     if (!cell
->Validate( value 
)) 
1882     wxDataViewModel 
*model 
= cell
->GetOwner()->GetOwner()->GetModel(); 
1884     GtkTreePath 
*gtk_path 
= gtk_tree_path_new_from_string( path 
); 
1886     cell
->GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter
, gtk_path 
); 
1887     wxDataViewItem 
item( (void*) iter
.user_data 
);; 
1888     gtk_tree_path_free( gtk_path 
); 
1890     unsigned int model_col 
= cell
->GetOwner()->GetModelColumn(); 
1892     model
->SetValue( value
, item
, model_col 
); 
1893     model
->ValueChanged( item
, model_col 
); 
1896 IMPLEMENT_CLASS(wxDataViewToggleRenderer
, wxDataViewRenderer
) 
1898 wxDataViewToggleRenderer::wxDataViewToggleRenderer( const wxString 
&varianttype
, 
1899                                                     wxDataViewCellMode mode
, int align 
) : 
1900     wxDataViewRenderer( varianttype
, mode
, align 
) 
1902     m_renderer 
= (GtkCellRenderer
*) gtk_cell_renderer_toggle_new(); 
1904     if (mode 
& wxDATAVIEW_CELL_ACTIVATABLE
) 
1906         g_signal_connect_after( m_renderer
, "toggled", 
1907                                 G_CALLBACK(wxGtkToggleRendererToggledCallback
), this ); 
1911         GValue gvalue 
= { 0, }; 
1912         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1913         g_value_set_boolean( &gvalue
, false ); 
1914         g_object_set_property( G_OBJECT(m_renderer
), "activatable", &gvalue 
); 
1915         g_value_unset( &gvalue 
); 
1919     SetAlignment(align
); 
1922 bool wxDataViewToggleRenderer::SetValue( const wxVariant 
&value 
) 
1926     GValue gvalue 
= { 0, }; 
1927     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1928     g_value_set_boolean( &gvalue
, tmp 
); 
1929     g_object_set_property( G_OBJECT(m_renderer
), "active", &gvalue 
); 
1930     g_value_unset( &gvalue 
); 
1935 bool wxDataViewToggleRenderer::GetValue( wxVariant 
&value 
) const 
1937     GValue gvalue 
= { 0, }; 
1938     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1939     g_object_get_property( G_OBJECT(m_renderer
), "active", &gvalue 
); 
1940     bool tmp 
= g_value_get_boolean( &gvalue 
); 
1941     g_value_unset( &gvalue 
); 
1948 // --------------------------------------------------------- 
1949 // wxDataViewCustomRenderer 
1950 // --------------------------------------------------------- 
1952 class wxDataViewCtrlDCImpl
: public wxWindowDCImpl
 
1955    wxDataViewCtrlDCImpl( wxDC 
*owner
, wxDataViewCtrl 
*window 
) : 
1956        wxWindowDCImpl( owner 
) 
1958         GtkWidget 
*widget 
= window
->m_treeview
; 
1964         m_context 
= window
->GTKGetPangoDefaultContext(); 
1965         m_layout 
= pango_layout_new( m_context 
); 
1966         m_fontdesc 
= pango_font_description_copy( widget
->style
->font_desc 
); 
1968         m_cmap 
= gtk_widget_get_colormap( widget 
? widget 
: window
->m_widget 
); 
1970         // Set m_gdkwindow later 
1975 class wxDataViewCtrlDC
: public wxWindowDC
 
1978     wxDataViewCtrlDC( wxDataViewCtrl 
*window 
) : 
1979         wxWindowDC( new wxDataViewCtrlDCImpl( this, window 
) ) 
1984 // --------------------------------------------------------- 
1985 // wxDataViewCustomRenderer 
1986 // --------------------------------------------------------- 
1988 IMPLEMENT_CLASS(wxDataViewCustomRenderer
, wxDataViewRenderer
) 
1990 wxDataViewCustomRenderer::wxDataViewCustomRenderer( const wxString 
&varianttype
, 
1991                                                     wxDataViewCellMode mode
, int align
, 
1993     wxDataViewRenderer( varianttype
, mode
, align 
) 
1996     m_text_renderer 
= NULL
; 
2004 void wxDataViewCustomRenderer::RenderText( const wxString 
&text
, int xoffset
, 
2005                                            wxRect 
WXUNUSED(cell
), wxDC 
*WXUNUSED(dc
), int WXUNUSED(state
) ) 
2008     wxDataViewCtrl 
*view 
= GetOwner()->GetOwner(); 
2009     wxColour col 
= (state 
& wxDATAVIEW_CELL_SELECTED
) ? 
2010                         wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT
) : 
2011                         view
->GetForegroundColour(); 
2012     dc
->SetTextForeground(col
); 
2013     dc
->DrawText( text
, cell
.x 
+ xoffset
, cell
.y 
+ ((cell
.height 
- dc
->GetCharHeight()) / 2)); 
2015     if (!m_text_renderer
) 
2016         m_text_renderer 
= gtk_cell_renderer_text_new(); 
2018     GValue gvalue 
= { 0, }; 
2019     g_value_init( &gvalue
, G_TYPE_STRING 
); 
2020     g_value_set_string( &gvalue
, wxGTK_CONV_FONT( text
, GetOwner()->GetOwner()->GetFont() ) ); 
2021     g_object_set_property( G_OBJECT(m_text_renderer
), "text", &gvalue 
); 
2022     g_value_unset( &gvalue 
); 
2024     ((GdkRectangle
*) cell_area
)->x 
+= xoffset
; 
2025     ((GdkRectangle
*) cell_area
)->width 
-= xoffset
; 
2027     gtk_cell_renderer_render( m_text_renderer
, 
2030         (GdkRectangle
*) background_area
, 
2031         (GdkRectangle
*) cell_area
, 
2032         (GdkRectangle
*) expose_area
, 
2033         (GtkCellRendererState
) flags 
); 
2035     ((GdkRectangle
*) cell_area
)->x 
-= xoffset
; 
2036     ((GdkRectangle
*) cell_area
)->width 
+= xoffset
; 
2040 bool wxDataViewCustomRenderer::Init(wxDataViewCellMode mode
, int align
) 
2042     GtkWxCellRenderer 
*renderer 
= (GtkWxCellRenderer 
*) gtk_wx_cell_renderer_new(); 
2043     renderer
->cell 
= this; 
2045     m_renderer 
= (GtkCellRenderer
*) renderer
; 
2048     SetAlignment(align
); 
2055 wxDataViewCustomRenderer::~wxDataViewCustomRenderer() 
2060     if (m_text_renderer
) 
2061         gtk_object_sink( GTK_OBJECT(m_text_renderer
) ); 
2064 wxDC 
*wxDataViewCustomRenderer::GetDC() 
2068         if (GetOwner() == NULL
) 
2070         if (GetOwner()->GetOwner() == NULL
) 
2072         m_dc 
= new wxDataViewCtrlDC( GetOwner()->GetOwner() ); 
2078 // --------------------------------------------------------- 
2079 // wxDataViewProgressRenderer 
2080 // --------------------------------------------------------- 
2082 IMPLEMENT_CLASS(wxDataViewProgressRenderer
, wxDataViewCustomRenderer
) 
2084 wxDataViewProgressRenderer::wxDataViewProgressRenderer( const wxString 
&label
, 
2085     const wxString 
&varianttype
, wxDataViewCellMode mode
, int align 
) : 
2086     wxDataViewCustomRenderer( varianttype
, mode
, align
, true ) 
2092     if (!gtk_check_version(2,6,0)) 
2094         m_renderer 
= (GtkCellRenderer
*) gtk_cell_renderer_progress_new(); 
2096         GValue gvalue 
= { 0, }; 
2097         g_value_init( &gvalue
, G_TYPE_STRING 
); 
2099         g_value_set_string( &gvalue
, wxGTK_CONV_FONT( m_label
, GetOwner()->GetOwner()->GetFont() ) ); 
2100         g_object_set_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
2101         g_value_unset( &gvalue 
); 
2104         SetAlignment(align
); 
2109         // Use custom cell code 
2110         wxDataViewCustomRenderer::Init(mode
, align
); 
2114 wxDataViewProgressRenderer::~wxDataViewProgressRenderer() 
2118 bool wxDataViewProgressRenderer::SetValue( const wxVariant 
&value 
) 
2121     if (!gtk_check_version(2,6,0)) 
2123         gint tmp 
= (long) value
; 
2124         GValue gvalue 
= { 0, }; 
2125         g_value_init( &gvalue
, G_TYPE_INT 
); 
2126         g_value_set_int( &gvalue
, tmp 
); 
2127         g_object_set_property( G_OBJECT(m_renderer
), "value", &gvalue 
); 
2128         g_value_unset( &gvalue 
); 
2133         m_value 
= (long) value
; 
2135         if (m_value 
< 0) m_value 
= 0; 
2136         if (m_value 
> 100) m_value 
= 100; 
2142 bool wxDataViewProgressRenderer::GetValue( wxVariant 
&WXUNUSED(value
) ) const 
2147 bool wxDataViewProgressRenderer::Render( wxRect cell
, wxDC 
*dc
, int WXUNUSED(state
) ) 
2149     double pct 
= (double)m_value 
/ 100.0; 
2151     bar
.width 
= (int)(cell
.width 
* pct
); 
2152     dc
->SetPen( *wxTRANSPARENT_PEN 
); 
2153     dc
->SetBrush( *wxBLUE_BRUSH 
); 
2154     dc
->DrawRectangle( bar 
); 
2156     dc
->SetBrush( *wxTRANSPARENT_BRUSH 
); 
2157     dc
->SetPen( *wxBLACK_PEN 
); 
2158     dc
->DrawRectangle( cell 
); 
2163 wxSize 
wxDataViewProgressRenderer::GetSize() const 
2165     return wxSize(40,12); 
2168 // ------------------------------------- 
2169 // wxDataViewChoiceRenderer 
2170 // ------------------------------------- 
2172 wxDataViewChoiceRenderer::wxDataViewChoiceRenderer( const wxArrayString 
&choices
, 
2173                             wxDataViewCellMode mode
, int alignment  
) : 
2174     wxDataViewCustomRenderer( "string", mode
, alignment
, true ) 
2176    m_choices 
= choices
; 
2179     if (!gtk_check_version(2,6,0)) 
2181         m_renderer 
= (GtkCellRenderer
*) gtk_cell_renderer_combo_new(); 
2183         GtkListStore 
*store 
= gtk_list_store_new( 1, G_TYPE_STRING 
); 
2184         for (size_t n 
= 0; n 
< m_choices
.GetCount(); n
++) 
2186             gtk_list_store_insert_with_values( 
2188                 static_cast<const char *>(m_choices
[n
].utf8_str()), -1 ); 
2191         g_object_set (m_renderer
, 
2197         bool editable 
= (mode 
& wxDATAVIEW_CELL_EDITABLE
); 
2198         g_object_set (m_renderer
, "editable", editable
, NULL
); 
2200         SetAlignment(alignment
); 
2202         g_signal_connect_after( m_renderer
, "edited", G_CALLBACK(wxGtkTextRendererEditedCallback
), this ); 
2209         // Use custom cell code 
2210         wxDataViewCustomRenderer::Init(mode
, alignment
); 
2214 bool wxDataViewChoiceRenderer::Render( wxRect rect
, wxDC 
*dc
, int state 
) 
2216     RenderText( m_data
, 0, rect
, dc
, state 
); 
2220 wxSize 
wxDataViewChoiceRenderer::GetSize() const 
2222     return wxSize(70,20); 
2225 bool wxDataViewChoiceRenderer::SetValue( const wxVariant 
&value 
) 
2229     if (!gtk_check_version(2,6,0)) 
2231         GValue gvalue 
= { 0, }; 
2232         g_value_init( &gvalue
, G_TYPE_STRING 
); 
2233         g_value_set_string( &gvalue
, wxGTK_CONV_FONT( value
.GetString(), GetOwner()->GetOwner()->GetFont() ) ); 
2234         g_object_set_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
2235         g_value_unset( &gvalue 
); 
2239         m_data 
= value
.GetString(); 
2244 bool wxDataViewChoiceRenderer::GetValue( wxVariant 
&value 
) const 
2247     if (!gtk_check_version(2,6,0)) 
2249         GValue gvalue 
= { 0, }; 
2250         g_value_init( &gvalue
, G_TYPE_STRING 
); 
2251         g_object_get_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
2252         wxString temp 
= wxGTK_CONV_BACK_FONT( g_value_get_string( &gvalue 
), 
2253                 const_cast<wxDataViewChoiceRenderer
*>(this)->GetOwner()->GetOwner()->GetFont() ); 
2254         g_value_unset( &gvalue 
); 
2257         //wxPrintf( "temp %s\n", temp ); 
2258         // TODO: remove this code 
2267 void wxDataViewChoiceRenderer::SetAlignment( int align 
) 
2269     wxDataViewCustomRenderer::SetAlignment(align
); 
2271     if (gtk_check_version(2,10,0)) 
2274     // horizontal alignment: 
2275     PangoAlignment pangoAlign 
= PANGO_ALIGN_LEFT
; 
2276     if (align 
& wxALIGN_RIGHT
) 
2277         pangoAlign 
= PANGO_ALIGN_RIGHT
; 
2278     else if (align 
& wxALIGN_CENTER_HORIZONTAL
) 
2279         pangoAlign 
= PANGO_ALIGN_CENTER
; 
2281     GValue gvalue 
= { 0, }; 
2282     g_value_init( &gvalue
, gtk_cell_renderer_mode_get_type() ); 
2283     g_value_set_enum( &gvalue
, pangoAlign 
); 
2284     g_object_set_property( G_OBJECT(m_renderer
), "alignment", &gvalue 
); 
2285     g_value_unset( &gvalue 
); 
2288 // --------------------------------------------------------- 
2289 // wxDataViewDateRenderer 
2290 // --------------------------------------------------------- 
2292 class wxDataViewDateRendererPopupTransient
: public wxPopupTransientWindow
 
2295     wxDataViewDateRendererPopupTransient( wxWindow
* parent
, wxDateTime 
*value
, 
2296         wxDataViewModel 
*model
, const wxDataViewItem 
&item
, unsigned int col 
) : 
2297         wxPopupTransientWindow( parent
, wxBORDER_SIMPLE 
) 
2302         m_cal 
= new wxCalendarCtrl( this, -1, *value 
); 
2303         wxBoxSizer 
*sizer 
= new wxBoxSizer( wxHORIZONTAL 
); 
2304         sizer
->Add( m_cal
, 1, wxGROW 
); 
2309     virtual void OnDismiss() 
2313     void OnCalendar( wxCalendarEvent 
&event 
); 
2315     wxCalendarCtrl   
*m_cal
; 
2316     wxDataViewModel  
*m_model
; 
2317     wxDataViewItem    m_item
; 
2321     DECLARE_EVENT_TABLE() 
2324 BEGIN_EVENT_TABLE(wxDataViewDateRendererPopupTransient
,wxPopupTransientWindow
) 
2325     EVT_CALENDAR( -1, wxDataViewDateRendererPopupTransient::OnCalendar 
) 
2328 void wxDataViewDateRendererPopupTransient::OnCalendar( wxCalendarEvent 
&event 
) 
2330     wxDateTime date 
= event
.GetDate(); 
2331     wxVariant value 
= date
; 
2332     m_model
->SetValue( value
, m_item
, m_col 
); 
2333     m_model
->ValueChanged( m_item
, m_col 
); 
2337 IMPLEMENT_CLASS(wxDataViewDateRenderer
, wxDataViewCustomRenderer
) 
2339 wxDataViewDateRenderer::wxDataViewDateRenderer( const wxString 
&varianttype
, 
2340                         wxDataViewCellMode mode
, int align 
) : 
2341     wxDataViewCustomRenderer( varianttype
, mode
, align 
) 
2344     SetAlignment(align
); 
2347 bool wxDataViewDateRenderer::SetValue( const wxVariant 
&value 
) 
2349     m_date 
= value
.GetDateTime(); 
2354 bool wxDataViewDateRenderer::GetValue( wxVariant 
&WXUNUSED(value
) ) const 
2359 bool wxDataViewDateRenderer::Render( wxRect cell
, wxDC 
*dc
, int state 
) 
2361     dc
->SetFont( GetOwner()->GetOwner()->GetFont() ); 
2362     wxString tmp 
= m_date
.FormatDate(); 
2363     RenderText( tmp
, 0, cell
, dc
, state 
); 
2367 wxSize 
wxDataViewDateRenderer::GetSize() const 
2369     wxString tmp 
= m_date
.FormatDate(); 
2371     GetView()->GetTextExtent( tmp
, &x
, &y
, &d 
); 
2372     return wxSize(x
,y
+d
); 
2375 bool wxDataViewDateRenderer::Activate( wxRect 
WXUNUSED(cell
), wxDataViewModel 
*model
, 
2376                                        const wxDataViewItem 
&item
, unsigned int col 
) 
2379     model
->GetValue( variant
, item
, col 
); 
2380     wxDateTime value 
= variant
.GetDateTime(); 
2382     wxDataViewDateRendererPopupTransient 
*popup 
= new wxDataViewDateRendererPopupTransient( 
2383         GetOwner()->GetOwner()->GetParent(), &value
, model
, item
, col 
); 
2384     wxPoint pos 
= wxGetMousePosition(); 
2387     popup
->Popup( popup
->m_cal 
); 
2393 // --------------------------------------------------------- 
2394 // wxDataViewIconTextRenderer 
2395 // --------------------------------------------------------- 
2397 IMPLEMENT_CLASS(wxDataViewIconTextRenderer
, wxDataViewCustomRenderer
) 
2399 wxDataViewIconTextRenderer::wxDataViewIconTextRenderer( 
2400   const wxString 
&varianttype
, wxDataViewCellMode mode
, int align 
) : 
2401     wxDataViewCustomRenderer( varianttype
, mode
, align 
) 
2404     SetAlignment(align
); 
2407 wxDataViewIconTextRenderer::~wxDataViewIconTextRenderer() 
2411 bool wxDataViewIconTextRenderer::SetValue( const wxVariant 
&value 
) 
2417 bool wxDataViewIconTextRenderer::GetValue( wxVariant 
&WXUNUSED(value
) ) const 
2422 bool wxDataViewIconTextRenderer::Render( wxRect cell
, wxDC 
*dc
, int state 
) 
2424     const wxIcon 
&icon 
= m_value
.GetIcon(); 
2428         int yoffset 
= wxMax( 0, (cell
.height 
- icon
.GetHeight()) / 2 ); 
2429         dc
->DrawIcon( icon
, cell
.x
, cell
.y 
+ yoffset 
); 
2430         offset 
= icon
.GetWidth() + 4; 
2433     RenderText( m_value
.GetText(), offset
, cell
, dc
, state 
); 
2438 wxSize 
wxDataViewIconTextRenderer::GetSize() const 
2441     if (m_value
.GetIcon().IsOk()) 
2442         size
.x 
= 4 + m_value
.GetIcon().GetWidth(); 
2444     GetView()->GetTextExtent( m_value
.GetText(), &x
, &y
, &d 
); 
2450 wxControl
* wxDataViewIconTextRenderer::CreateEditorCtrl( 
2451     wxWindow 
*WXUNUSED(parent
), wxRect 
WXUNUSED(labelRect
), const wxVariant 
&WXUNUSED(value
) ) 
2456 bool wxDataViewIconTextRenderer::GetValueFromEditorCtrl( 
2457    wxControl
* WXUNUSED(editor
), wxVariant 
&WXUNUSED(value
) ) 
2462 // --------------------------------------------------------- 
2464 // --------------------------------------------------------- 
2468 gtk_dataview_header_button_press_callback( GtkWidget 
*WXUNUSED(widget
), 
2469                                            GdkEventButton 
*gdk_event
, 
2470                                            wxDataViewColumn 
*column 
) 
2472     if (gdk_event
->type 
!= GDK_BUTTON_PRESS
) 
2475     if (gdk_event
->button 
== 1) 
2477         gs_lastLeftClickHeader 
= column
; 
2479         wxDataViewCtrl 
*dv 
= column
->GetOwner(); 
2480         wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK
, dv
->GetId() ); 
2481         event
.SetDataViewColumn( column 
); 
2482         event
.SetModel( dv
->GetModel() ); 
2483         if (dv
->HandleWindowEvent( event 
)) 
2487     if (gdk_event
->button 
== 3) 
2489         wxDataViewCtrl 
*dv 
= column
->GetOwner(); 
2490         wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK
, dv
->GetId() ); 
2491         event
.SetDataViewColumn( column 
); 
2492         event
.SetModel( dv
->GetModel() ); 
2493         if (dv
->HandleWindowEvent( event 
)) 
2503 static void wxGtkTreeCellDataFunc( GtkTreeViewColumn 
*WXUNUSED(column
), 
2504                             GtkCellRenderer 
*renderer
, 
2505                             GtkTreeModel 
*model
, 
2509     g_return_if_fail (GTK_IS_WX_TREE_MODEL (model
)); 
2510     GtkWxTreeModel 
*tree_model 
= (GtkWxTreeModel 
*) model
; 
2512     wxDataViewRenderer 
*cell 
= (wxDataViewRenderer
*) data
; 
2514     wxDataViewItem 
item( (void*) iter
->user_data 
); 
2516     wxDataViewModel 
*wx_model 
= tree_model
->internal
->GetDataViewModel(); 
2518     if (!wx_model
->IsVirtualListModel()) 
2521         if (wx_model
->IsContainer( item 
)) 
2523             visible 
= wx_model
->HasContainerColumns( item 
) || 
2524                         (cell
->GetOwner()->GetModelColumn() == 0); 
2531         GValue gvalue 
= { 0, }; 
2532         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
2533         g_value_set_boolean( &gvalue
, visible 
); 
2534         g_object_set_property( G_OBJECT(renderer
), "visible", &gvalue 
); 
2535         g_value_unset( &gvalue 
); 
2542     wx_model
->GetValue( value
, item
, cell
->GetOwner()->GetModelColumn() ); 
2544     if (value
.GetType() != cell
->GetVariantType()) 
2546         wxLogError( wxT("Wrong type, required: %s but: %s"), 
2547                     value
.GetType().c_str(), 
2548                     cell
->GetVariantType().c_str() ); 
2551     cell
->SetValue( value 
); 
2553     wxDataViewItemAttr attr
; 
2554     if (wx_model
->GetAttr( item
, cell
->GetOwner()->GetModelColumn(), attr 
)) 
2556         if (attr
.HasColour()) 
2558             const GdkColor 
* const gcol 
= attr
.GetColour().GetColor(); 
2560             GValue gvalue 
= { 0, }; 
2561             g_value_init( &gvalue
, GDK_TYPE_COLOR 
); 
2562             g_value_set_boxed( &gvalue
, gcol 
); 
2563             g_object_set_property( G_OBJECT(renderer
), "foreground_gdk", &gvalue 
); 
2564             g_value_unset( &gvalue 
); 
2568             GValue gvalue 
= { 0, }; 
2569             g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
2570             g_value_set_boolean( &gvalue
, FALSE 
); 
2571             g_object_set_property( G_OBJECT(renderer
), "foreground-set", &gvalue 
); 
2572             g_value_unset( &gvalue 
); 
2575         if (attr
.GetItalic()) 
2577             GValue gvalue 
= { 0, }; 
2578             g_value_init( &gvalue
, PANGO_TYPE_STYLE 
); 
2579             g_value_set_enum( &gvalue
, PANGO_STYLE_ITALIC 
); 
2580             g_object_set_property( G_OBJECT(renderer
), "style", &gvalue 
); 
2581             g_value_unset( &gvalue 
); 
2585             GValue gvalue 
= { 0, }; 
2586             g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
2587             g_value_set_boolean( &gvalue
, FALSE 
); 
2588             g_object_set_property( G_OBJECT(renderer
), "style-set", &gvalue 
); 
2589             g_value_unset( &gvalue 
); 
2595             GValue gvalue 
= { 0, }; 
2596             g_value_init( &gvalue
, PANGO_TYPE_WEIGHT 
); 
2597             g_value_set_enum( &gvalue
, PANGO_WEIGHT_BOLD 
); 
2598             g_object_set_property( G_OBJECT(renderer
), "weight", &gvalue 
); 
2599             g_value_unset( &gvalue 
); 
2603             GValue gvalue 
= { 0, }; 
2604             g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
2605             g_value_set_boolean( &gvalue
, FALSE 
); 
2606             g_object_set_property( G_OBJECT(renderer
), "weight-set", &gvalue 
); 
2607             g_value_unset( &gvalue 
); 
2612     if (attr
.HasBackgroundColour()) 
2614         wxColour colour 
= attr
.GetBackgroundColour(); 
2615         const GdkColor 
* const gcol 
= colour
.GetColor(); 
2617         GValue gvalue 
= { 0, }; 
2618         g_value_init( &gvalue
, GDK_TYPE_COLOR 
); 
2619         g_value_set_boxed( &gvalue
, gcol 
); 
2620         g_object_set_property( G_OBJECT(renderer
), "cell-background_gdk", &gvalue 
); 
2621         g_value_unset( &gvalue 
); 
2625         GValue gvalue 
= { 0, }; 
2626         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
2627         g_value_set_boolean( &gvalue
, FALSE 
); 
2628         g_object_set_property( G_OBJECT(renderer
), "cell-background-set", &gvalue 
); 
2629         g_value_unset( &gvalue 
); 
2637 #include <wx/listimpl.cpp> 
2638 WX_DEFINE_LIST(wxDataViewColumnList
) 
2640 wxDataViewColumn::wxDataViewColumn( const wxString 
&title
, wxDataViewRenderer 
*cell
, 
2641                                     unsigned int model_column
, int width
, 
2642                                     wxAlignment align
, int flags 
) 
2643     : wxDataViewColumnBase( cell
, model_column 
) 
2645     Init( align
, flags
, width 
); 
2650 wxDataViewColumn::wxDataViewColumn( const wxBitmap 
&bitmap
, wxDataViewRenderer 
*cell
, 
2651                                     unsigned int model_column
, int width
, 
2652                                     wxAlignment align
, int flags 
) 
2653     : wxDataViewColumnBase( bitmap
, cell
, model_column 
) 
2655     Init( align
, flags
, width 
); 
2657     SetBitmap( bitmap 
); 
2660 void wxDataViewColumn::Init(wxAlignment align
, int flags
, int width
) 
2662     m_isConnected 
= false; 
2664     GtkCellRenderer 
*renderer 
= (GtkCellRenderer 
*) GetRenderer()->GetGtkHandle(); 
2665     GtkTreeViewColumn 
*column 
= gtk_tree_view_column_new(); 
2666     m_column 
= (GtkWidget
*) column
; 
2669     SetAlignment( align 
); 
2673     // Create container for icon and label 
2674     GtkWidget 
*box 
= gtk_hbox_new( FALSE
, 1 ); 
2675     gtk_widget_show( box 
); 
2676     // gtk_container_set_border_width((GtkContainer*)box, 2); 
2677     m_image 
= gtk_image_new(); 
2678     gtk_box_pack_start(GTK_BOX(box
), m_image
, FALSE
, FALSE
, 1); 
2679     m_label 
= gtk_label_new(""); 
2680     gtk_box_pack_end( GTK_BOX(box
), GTK_WIDGET(m_label
), FALSE
, FALSE
, 1 ); 
2681     gtk_tree_view_column_set_widget( column
, box 
); 
2683     gtk_tree_view_column_pack_end( column
, renderer
, TRUE 
); 
2685     gtk_tree_view_column_set_cell_data_func( column
, renderer
, 
2686         wxGtkTreeCellDataFunc
, (gpointer
) GetRenderer(), NULL 
); 
2689 void wxDataViewColumn::OnInternalIdle() 
2694     if (GTK_WIDGET_REALIZED(GetOwner()->m_treeview
)) 
2696         GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2699             g_signal_connect(column
->button
, "button_press_event", 
2700                       G_CALLBACK (gtk_dataview_header_button_press_callback
), this); 
2702             m_isConnected 
= true; 
2707 void wxDataViewColumn::SetOwner( wxDataViewCtrl 
*owner 
) 
2709     wxDataViewColumnBase::SetOwner( owner 
); 
2711     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2713     gtk_tree_view_column_set_title( column
, wxGTK_CONV_FONT(GetTitle(), GetOwner()->GetFont() ) ); 
2716 void wxDataViewColumn::SetTitle( const wxString 
&title 
) 
2718     wxDataViewCtrl 
*ctrl 
= GetOwner(); 
2719     gtk_label_set_text( GTK_LABEL(m_label
), ctrl 
? wxGTK_CONV_FONT(title
, ctrl
->GetFont()) 
2720                                                  : wxGTK_CONV_SYS(title
) ); 
2722         gtk_widget_hide( m_label 
); 
2724         gtk_widget_show( m_label 
); 
2727 wxString 
wxDataViewColumn::GetTitle() const 
2729     return wxGTK_CONV_BACK_FONT( 
2730             gtk_label_get_text( GTK_LABEL(m_label
) ), 
2731             GetOwner()->GetFont() 
2735 void wxDataViewColumn::SetBitmap( const wxBitmap 
&bitmap 
) 
2737     wxDataViewColumnBase::SetBitmap( bitmap 
); 
2741         GtkImage 
*gtk_image 
= GTK_IMAGE(m_image
); 
2743         GdkBitmap 
*mask 
= NULL
; 
2744         if (bitmap
.GetMask()) 
2745             mask 
= bitmap
.GetMask()->GetBitmap(); 
2747         if (bitmap
.HasPixbuf()) 
2749             gtk_image_set_from_pixbuf(GTK_IMAGE(gtk_image
), 
2750                                       bitmap
.GetPixbuf()); 
2754             gtk_image_set_from_pixmap(GTK_IMAGE(gtk_image
), 
2755                                       bitmap
.GetPixmap(), mask
); 
2757         gtk_widget_show( m_image 
); 
2761         gtk_widget_hide( m_image 
); 
2765 void wxDataViewColumn::SetHidden( bool hidden 
) 
2767     gtk_tree_view_column_set_visible( GTK_TREE_VIEW_COLUMN(m_column
), !hidden 
); 
2770 void wxDataViewColumn::SetResizeable( bool resizeable 
) 
2772     gtk_tree_view_column_set_resizable( GTK_TREE_VIEW_COLUMN(m_column
), resizeable 
); 
2775 void wxDataViewColumn::SetAlignment( wxAlignment align 
) 
2777     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2779     gfloat xalign 
= 0.0; 
2780     if (align 
== wxALIGN_RIGHT
) 
2782     if (align 
== wxALIGN_CENTER_HORIZONTAL 
|| 
2783         align 
== wxALIGN_CENTER
) 
2786     gtk_tree_view_column_set_alignment( column
, xalign 
); 
2788     if (m_renderer 
&& m_renderer
->GetAlignment() == -1) 
2789         m_renderer
->GtkUpdateAlignment(); 
2792 wxAlignment 
wxDataViewColumn::GetAlignment() const 
2794     gfloat xalign 
= gtk_tree_view_column_get_alignment( GTK_TREE_VIEW_COLUMN(m_column
) ); 
2797         return wxALIGN_RIGHT
; 
2799         return wxALIGN_CENTER_HORIZONTAL
; 
2801     return wxALIGN_LEFT
; 
2804 void wxDataViewColumn::SetSortable( bool sortable 
) 
2806     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2810         gtk_tree_view_column_set_sort_column_id( column
, GetModelColumn() ); 
2814         gtk_tree_view_column_set_sort_column_id( column
, -1 ); 
2815         gtk_tree_view_column_set_sort_indicator( column
, FALSE 
); 
2816         gtk_tree_view_column_set_clickable( column
, FALSE 
); 
2820 bool wxDataViewColumn::IsSortable() const 
2822     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2823     return gtk_tree_view_column_get_clickable( column 
); 
2826 void wxDataViewColumn::SetAsSortKey( bool WXUNUSED(sort
) ) 
2828     // it might not make sense to have this function in wxHeaderColumn at 
2829     // all in fact, changing of the sort order should only be done using the 
2830     // associated control API 
2831     wxFAIL_MSG( "not implemented" ); 
2834 bool wxDataViewColumn::IsSortKey() const 
2836     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2837     return gtk_tree_view_column_get_sort_indicator( column 
); 
2840 bool wxDataViewColumn::IsResizeable() const 
2842     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2843     return gtk_tree_view_column_get_resizable( column 
); 
2846 bool wxDataViewColumn::IsHidden() const 
2848     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2849     return !gtk_tree_view_column_get_visible( column 
); 
2852 void wxDataViewColumn::SetSortOrder( bool ascending 
) 
2854     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2857         gtk_tree_view_column_set_sort_order( column
, GTK_SORT_ASCENDING 
); 
2859         gtk_tree_view_column_set_sort_order( column
, GTK_SORT_DESCENDING 
); 
2861     gtk_tree_view_column_set_sort_indicator( column
, TRUE 
); 
2864 bool wxDataViewColumn::IsSortOrderAscending() const 
2866     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2868     return (gtk_tree_view_column_get_sort_order( column 
) != GTK_SORT_DESCENDING
); 
2871 void wxDataViewColumn::SetMinWidth( int width 
) 
2873     gtk_tree_view_column_set_min_width( GTK_TREE_VIEW_COLUMN(m_column
), width 
); 
2876 int wxDataViewColumn::GetMinWidth() const 
2878     return gtk_tree_view_column_get_min_width( GTK_TREE_VIEW_COLUMN(m_column
) ); 
2881 int wxDataViewColumn::GetWidth() const 
2883     return gtk_tree_view_column_get_width( GTK_TREE_VIEW_COLUMN(m_column
) ); 
2886 void wxDataViewColumn::SetWidth( int width 
) 
2891         gtk_tree_view_column_set_sizing( GTK_TREE_VIEW_COLUMN(m_column
), GTK_TREE_VIEW_COLUMN_FIXED 
); 
2893         // TODO find a better calculation 
2894         gtk_tree_view_column_set_fixed_width( GTK_TREE_VIEW_COLUMN(m_column
), wxDVC_DEFAULT_WIDTH 
); 
2896         // this is unpractical for large numbers of items and disables 
2897         // user resizing, which is totally unexpected 
2898         gtk_tree_view_column_set_sizing( GTK_TREE_VIEW_COLUMN(m_column
), GTK_TREE_VIEW_COLUMN_AUTOSIZE 
); 
2903         gtk_tree_view_column_set_sizing( GTK_TREE_VIEW_COLUMN(m_column
), GTK_TREE_VIEW_COLUMN_FIXED 
); 
2905         gtk_tree_view_column_set_fixed_width( GTK_TREE_VIEW_COLUMN(m_column
), width 
); 
2909 void wxDataViewColumn::SetReorderable( bool reorderable 
) 
2911     gtk_tree_view_column_set_reorderable( GTK_TREE_VIEW_COLUMN(m_column
), reorderable 
); 
2914 bool wxDataViewColumn::IsReorderable() const 
2916     return gtk_tree_view_column_get_reorderable( GTK_TREE_VIEW_COLUMN(m_column
) ); 
2919 //----------------------------------------------------------------------------- 
2920 // wxGtkTreeModelNode 
2921 //----------------------------------------------------------------------------- 
2924 class wxGtkTreeModelChildWithPos
 
2932 int wxGtkTreeModelChildWithPosCmp( const void* data1
, const void* data2
, const void* user_data 
) 
2934     const wxGtkTreeModelChildWithPos
* child1 
= (const wxGtkTreeModelChildWithPos
*) data1
; 
2935     const wxGtkTreeModelChildWithPos
* child2 
= (const wxGtkTreeModelChildWithPos
*) data2
; 
2936     const wxDataViewCtrlInternal 
*internal 
= (const wxDataViewCtrlInternal 
*) user_data
; 
2937     int ret 
= internal
->GetDataViewModel()->Compare( child1
->id
, child2
->id
, 
2938         internal
->GetSortColumn(), (internal
->GetSortOrder() == GTK_SORT_DESCENDING
) ); 
2944 int LINKAGEMODE 
wxGtkTreeModelChildPtrCmp( void*** data1
, void*** data2 
) 
2946     return gs_internal
->GetDataViewModel()->Compare( **data1
, **data2
, 
2947         gs_internal
->GetSortColumn(), (gs_internal
->GetSortOrder() == GTK_SORT_ASCENDING
) ); 
2950 WX_DEFINE_ARRAY_PTR( void**, wxGtkTreeModelChildrenPtr 
); 
2953 void wxGtkTreeModelNode::Resort() 
2955     size_t child_count 
= GetChildCount(); 
2956     if (child_count 
== 0) 
2959     size_t node_count 
= GetNodesCount(); 
2961     if (child_count 
== 1) 
2963         if (node_count 
== 1) 
2965             wxGtkTreeModelNode 
*node 
= m_nodes
.Item( 0 ); 
2971     gint 
*new_order 
= new gint
[child_count
]; 
2974     // m_children has the original *void 
2975     // ptrs points to these 
2976     wxGtkTreeModelChildrenPtr ptrs
; 
2978     for (i 
= 0; i 
< child_count
; i
++) 
2979        ptrs
.Add( &(m_children
[i
]) ); 
2981     gs_internal 
= m_internal
; 
2982     ptrs
.Sort( &wxGtkTreeModelChildPtrCmp 
); 
2984     wxGtkTreeModelChildren temp
; 
2985     void** base_ptr 
= &(m_children
[0]); 
2986     // Transfer positions to new_order array and 
2988     for (i 
= 0; i 
< child_count
; i
++) 
2990         new_order
[i
] = ptrs
[i
] - base_ptr
; 
2991         temp
.Add( *ptrs
[i
] ); 
2994     // Transfer IDs back to m_children 
2996     WX_APPEND_ARRAY( temp
, m_children 
); 
3001     // Build up array with IDs and original positions 
3002     wxGtkTreeModelChildWithPos
* temp 
= new wxGtkTreeModelChildWithPos
[child_count
]; 
3004     for (i 
= 0; i 
< child_count
; i
++) 
3007        temp
[i
].id 
= m_children
[i
]; 
3009     // Sort array keeping original positions 
3010     wxQsort( temp
, child_count
, sizeof(wxGtkTreeModelChildWithPos
), 
3011              &wxGtkTreeModelChildWithPosCmp
, m_internal 
); 
3012     // Transfer positions to new_order array and 
3013     // IDs to m_children 
3015     for (i 
= 0; i 
< child_count
; i
++) 
3017        new_order
[i
] = temp
[i
].pos
; 
3018        m_children
.Add( temp
[i
].id 
); 
3027     wxGtkTreeModelChildren temp
; 
3028     WX_APPEND_ARRAY( temp
, m_children 
); 
3030     gs_internal 
= m_internal
; 
3031     m_children
.Sort( &wxGtkTreeModelChildCmp 
); 
3034     for (pos 
= 0; pos 
< child_count
; pos
++) 
3036         void *id 
= m_children
.Item( pos 
); 
3037         int old_pos 
= temp
.Index( id 
); 
3038         new_order
[pos
] = old_pos
; 
3042     GtkTreeModel 
*gtk_tree_model 
= GTK_TREE_MODEL( m_internal
->GetGtkModel() ); 
3045     iter
.user_data 
= GetItem().GetID(); 
3046     iter
.stamp 
= m_internal
->GetGtkModel()->stamp
; 
3048     GtkTreePath 
*path 
= m_internal
->get_path( &iter 
); 
3050     gtk_tree_model_rows_reordered( gtk_tree_model
, path
, &iter
, new_order 
); 
3052     gtk_tree_path_free (path
); 
3054     delete [] new_order
; 
3057     for (pos 
= 0; pos 
< node_count
; pos
++) 
3059         wxGtkTreeModelNode 
*node 
= m_nodes
.Item( pos 
); 
3064 //----------------------------------------------------------------------------- 
3065 // wxDataViewCtrlInternal 
3066 //----------------------------------------------------------------------------- 
3068 wxDataViewCtrlInternal::wxDataViewCtrlInternal( wxDataViewCtrl 
*owner
, 
3069     wxDataViewModel 
*wx_model
, GtkWxTreeModel 
*gtk_model 
) 
3072     m_wx_model 
= wx_model
; 
3073     m_gtk_model 
= gtk_model
; 
3075     m_sort_order 
= GTK_SORT_ASCENDING
; 
3077     m_dataview_sort_column 
= NULL
; 
3079     m_dragDataObject 
= NULL
; 
3080     m_dropDataObject 
= NULL
; 
3082     if (!m_wx_model
->IsVirtualListModel()) 
3086 wxDataViewCtrlInternal::~wxDataViewCtrlInternal() 
3088     g_object_unref( m_gtk_model 
); 
3090     delete m_dragDataObject
; 
3091     delete m_dropDataObject
; 
3094 void wxDataViewCtrlInternal::InitTree() 
3096     wxDataViewItem item
; 
3097     m_root 
= new wxGtkTreeModelNode( NULL
, item
, this ); 
3099     BuildBranch( m_root 
); 
3102 void wxDataViewCtrlInternal::BuildBranch( wxGtkTreeModelNode 
*node 
) 
3104     if (node
->GetChildCount() == 0) 
3106         wxDataViewItemArray children
; 
3107         unsigned int count 
= m_wx_model
->GetChildren( node
->GetItem(), children 
); 
3109         for (pos 
= 0; pos 
< count
; pos
++) 
3111             wxDataViewItem child 
= children
[pos
]; 
3113             if (m_wx_model
->IsContainer( child 
)) 
3114                 node
->AddNode( new wxGtkTreeModelNode( node
, child
, this ) ); 
3116                 node
->AddLeave( child
.GetID() ); 
3118             // Don't send any events here 
3125 bool wxDataViewCtrlInternal::EnableDragSource( const wxDataFormat 
&format 
) 
3127     wxGtkString 
atom_str( gdk_atom_name( format  
) ); 
3128     m_dragSourceTargetEntryTarget 
= wxCharBuffer( atom_str 
); 
3130     m_dragSourceTargetEntry
.target 
=  m_dragSourceTargetEntryTarget
.data(); 
3131     m_dragSourceTargetEntry
.flags 
= 0; 
3132     m_dragSourceTargetEntry
.info 
= static_cast<guint
>(-1); 
3134     gtk_tree_view_enable_model_drag_source( GTK_TREE_VIEW(m_owner
->GtkGetTreeView() ), 
3135        GDK_BUTTON1_MASK
, &m_dragSourceTargetEntry
, 1, (GdkDragAction
) GDK_ACTION_COPY 
); 
3140 bool wxDataViewCtrlInternal::EnableDropTarget( const wxDataFormat 
&format 
) 
3142     wxGtkString 
atom_str( gdk_atom_name( format  
) ); 
3143     m_dropTargetTargetEntryTarget 
= wxCharBuffer( atom_str 
); 
3145     m_dropTargetTargetEntry
.target 
=  m_dropTargetTargetEntryTarget
.data(); 
3146     m_dropTargetTargetEntry
.flags 
= 0; 
3147     m_dropTargetTargetEntry
.info 
= static_cast<guint
>(-1); 
3149     gtk_tree_view_enable_model_drag_dest( GTK_TREE_VIEW(m_owner
->GtkGetTreeView() ), 
3150        &m_dropTargetTargetEntry
, 1, (GdkDragAction
) GDK_ACTION_COPY 
); 
3155 gboolean 
wxDataViewCtrlInternal::row_draggable( GtkTreeDragSource 
*WXUNUSED(drag_source
), 
3158     delete m_dragDataObject
; 
3161     if (!get_iter( &iter
, path 
)) return FALSE
; 
3162     wxDataViewItem 
item( (void*) iter
.user_data 
); 
3164     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_BEGIN_DRAG
, m_owner
->GetId() ); 
3165     event
.SetEventObject( m_owner 
); 
3166     event
.SetItem( item 
); 
3167     event
.SetModel( m_wx_model 
); 
3168     if (!m_owner
->HandleWindowEvent( event 
)) 
3171     if (!event
.IsAllowed()) 
3174     wxDataObject 
*obj 
= event
.GetDataObject(); 
3178     m_dragDataObject 
= obj
; 
3184 wxDataViewCtrlInternal::drag_data_delete(GtkTreeDragSource 
*WXUNUSED(drag_source
), 
3185                                          GtkTreePath 
*WXUNUSED(path
)) 
3190 gboolean 
wxDataViewCtrlInternal::drag_data_get( GtkTreeDragSource 
*WXUNUSED(drag_source
), 
3191     GtkTreePath 
*path
, GtkSelectionData 
*selection_data 
) 
3194     if (!get_iter( &iter
, path 
)) return FALSE
; 
3195     wxDataViewItem 
item( (void*) iter
.user_data 
); 
3197     if (!m_dragDataObject
->IsSupported( selection_data
->target 
)) 
3200     size_t size 
= m_dragDataObject
->GetDataSize( selection_data
->target 
); 
3204     void *buf 
= malloc( size 
); 
3206     gboolean res 
= FALSE
; 
3207     if (m_dragDataObject
->GetDataHere( selection_data
->target
, buf 
)) 
3211         gtk_selection_data_set( selection_data
, selection_data
->target
, 
3212             8, (const guchar
*) buf
, size 
); 
3221 wxDataViewCtrlInternal::drag_data_received(GtkTreeDragDest 
*WXUNUSED(drag_dest
), 
3223                                            GtkSelectionData 
*selection_data
) 
3226     if (!get_iter( &iter
, path 
)) return FALSE
; 
3227     wxDataViewItem 
item( (void*) iter
.user_data 
); 
3229     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_DROP
, m_owner
->GetId() ); 
3230     event
.SetEventObject( m_owner 
); 
3231     event
.SetItem( item 
); 
3232     event
.SetModel( m_wx_model 
); 
3233     event
.SetDataFormat( selection_data
->target 
); 
3234     event
.SetDataSize( selection_data
->length 
); 
3235     event
.SetDataBuffer( selection_data
->data 
); 
3236     if (!m_owner
->HandleWindowEvent( event 
)) 
3239     if (!event
.IsAllowed()) 
3246 wxDataViewCtrlInternal::row_drop_possible(GtkTreeDragDest 
*WXUNUSED(drag_dest
), 
3248                                           GtkSelectionData 
*selection_data
) 
3251     if (!get_iter( &iter
, path 
)) return FALSE
; 
3252     wxDataViewItem 
item( (void*) iter
.user_data 
); 
3254     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_DROP_POSSIBLE
, m_owner
->GetId() ); 
3255     event
.SetEventObject( m_owner 
); 
3256     event
.SetItem( item 
); 
3257     event
.SetModel( m_wx_model 
); 
3258     event
.SetDataFormat( selection_data
->target 
); 
3259     if (!m_owner
->HandleWindowEvent( event 
)) 
3262     if (!event
.IsAllowed()) 
3268 // notifications from wxDataViewModel 
3270 bool wxDataViewCtrlInternal::Cleared() 
3272     GtkWidget
* tree_widget 
= GetOwner()->GtkGetTreeView(); 
3273     gtk_tree_view_set_model( GTK_TREE_VIEW(tree_widget
), NULL 
); 
3274     gtk_tree_view_set_model( GTK_TREE_VIEW(tree_widget
), GTK_TREE_MODEL(m_gtk_model
) ); 
3285 void wxDataViewCtrlInternal::Resort() 
3287     if (!m_wx_model
->IsVirtualListModel()) 
3291 bool wxDataViewCtrlInternal::ItemAdded( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
) 
3293     if (!m_wx_model
->IsVirtualListModel()) 
3295         wxGtkTreeModelNode 
*parent_node 
= FindNode( parent 
); 
3296         wxASSERT_MSG(parent_node
, 
3297             "Did you forget a call to ItemAdded()? The parent node is unknown to the wxGtkTreeModel"); 
3299         if (m_wx_model
->IsContainer( item 
)) 
3300             parent_node
->AddNode( new wxGtkTreeModelNode( parent_node
, item
, this ) ); 
3302             parent_node
->AddLeave( item
.GetID() ); 
3308 bool wxDataViewCtrlInternal::ItemDeleted( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
) 
3310     if (!m_wx_model
->IsVirtualListModel()) 
3312         wxGtkTreeModelNode 
*parent_node 
= FindNode( parent 
); 
3313         wxASSERT_MSG(parent_node
, 
3314             "Did you forget a call to ItemAdded()? The parent node is unknown to the wxGtkTreeModel"); 
3316         parent_node
->DeleteChild( item
.GetID() ); 
3322 bool wxDataViewCtrlInternal::ItemChanged( const wxDataViewItem 
&item 
) 
3324     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED
, m_owner
->GetId() ); 
3325     event
.SetEventObject( m_owner 
); 
3326     event
.SetModel( m_owner
->GetModel() ); 
3327     event
.SetItem( item 
); 
3328     m_owner
->HandleWindowEvent( event 
); 
3333 bool wxDataViewCtrlInternal::ValueChanged( const wxDataViewItem 
&item
, unsigned int col 
) 
3335     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED
, m_owner
->GetId() ); 
3336     event
.SetEventObject( m_owner 
); 
3337     event
.SetModel( m_owner
->GetModel() ); 
3338     event
.SetColumn( col 
); 
3339     event
.SetDataViewColumn( GetOwner()->GetColumn(col
) ); 
3340     event
.SetItem( item 
); 
3341     m_owner
->HandleWindowEvent( event 
); 
3348 GtkTreeModelFlags 
wxDataViewCtrlInternal::get_flags() 
3350     if (m_wx_model
->IsVirtualListModel()) 
3351         return GTK_TREE_MODEL_LIST_ONLY
; 
3353         return GTK_TREE_MODEL_ITERS_PERSIST
; 
3356 gboolean 
wxDataViewCtrlInternal::get_iter( GtkTreeIter 
*iter
, GtkTreePath 
*path 
) 
3359     if (m_wx_model
->IsVirtualListModel()) 
3361         wxDataViewVirtualListModel 
*wx_model 
= (wxDataViewVirtualListModel
*) m_wx_model
; 
3363         unsigned int i 
= (unsigned int)gtk_tree_path_get_indices (path
)[0]; 
3365         if (i 
>= wx_model
->GetCount()) 
3368         iter
->stamp 
= m_gtk_model
->stamp
; 
3369         // user_data is just the index +1 
3370         iter
->user_data 
= (gpointer
) (i
+1); 
3376         int depth 
= gtk_tree_path_get_depth( path 
); 
3378         wxGtkTreeModelNode 
*node 
= m_root
; 
3381         for (i 
= 0; i 
< depth
; i
++) 
3383             BuildBranch( node 
); 
3385             gint pos 
= gtk_tree_path_get_indices (path
)[i
]; 
3386             if (pos 
< 0) return FALSE
; 
3387             if ((size_t)pos 
>= node
->GetChildCount()) return FALSE
; 
3389             void* id 
= node
->GetChildren().Item( (size_t) pos 
); 
3393                 iter
->stamp 
= m_gtk_model
->stamp
; 
3394                 iter
->user_data 
= id
; 
3398             size_t count 
= node
->GetNodes().GetCount(); 
3400             for (pos2 
= 0; pos2 
< count
; pos2
++) 
3402                 wxGtkTreeModelNode 
*child_node 
= node
->GetNodes().Item( pos2 
); 
3403                 if (child_node
->GetItem().GetID() == id
) 
3415 GtkTreePath 
*wxDataViewCtrlInternal::get_path( GtkTreeIter 
*iter 
) 
3417     GtkTreePath 
*retval 
= gtk_tree_path_new (); 
3419     if (m_wx_model
->IsVirtualListModel()) 
3421         // user_data is just the index +1 
3422         int i 
= ( (wxUIntPtr
) iter
->user_data 
) -1; 
3423         gtk_tree_path_append_index (retval
, i
); 
3427         void *id 
= iter
->user_data
; 
3429         wxGtkTreeModelNode 
*node 
= FindParentNode( iter 
); 
3432             int pos 
= node
->GetChildren().Index( id 
); 
3434             gtk_tree_path_prepend_index( retval
, pos 
); 
3436             id 
= node
->GetItem().GetID(); 
3437             node 
= node
->GetParent(); 
3444 gboolean 
wxDataViewCtrlInternal::iter_next( GtkTreeIter 
*iter 
) 
3446     if (m_wx_model
->IsVirtualListModel()) 
3448         wxDataViewVirtualListModel 
*wx_model 
= (wxDataViewVirtualListModel
*) m_wx_model
; 
3450         // user_data is just the index +1 
3451         int n 
= ( (wxUIntPtr
) iter
->user_data 
) -1; 
3455             iter
->user_data 
= NULL
; 
3459         if (n 
>= (int) wx_model
->GetCount()-1) 
3461             iter
->user_data 
= NULL
; 
3465         // user_data is just the index +1 (+2 because we need the next) 
3466         iter
->user_data 
= (gpointer
) (n
+2); 
3470         wxGtkTreeModelNode 
*parent 
= FindParentNode( iter 
); 
3471         if( parent 
== NULL 
) 
3473             iter
->user_data 
= NULL
; 
3477         int pos 
= parent
->GetChildren().Index( iter
->user_data 
); 
3479         if (pos 
== (int) parent
->GetChildCount()-1) 
3481             iter
->user_data 
= NULL
; 
3485         iter
->user_data 
= parent
->GetChildren().Item( pos
+1 ); 
3491 gboolean 
wxDataViewCtrlInternal::iter_children( GtkTreeIter 
*iter
, GtkTreeIter 
*parent 
) 
3493     if (m_wx_model
->IsVirtualListModel()) 
3495         // this is a list, nodes have no children 
3499         iter
->stamp 
= m_gtk_model
->stamp
; 
3500         iter
->user_data 
= (gpointer
) 1; 
3508             if (m_root
->GetChildCount() == 0) return FALSE
; 
3509             iter
->stamp 
= m_gtk_model
->stamp
; 
3510             iter
->user_data 
= (gpointer
) m_root
->GetChildren().Item( 0 ); 
3514         wxDataViewItem 
item( (void*) parent
->user_data 
); 
3516         if (!m_wx_model
->IsContainer( item 
)) 
3519         wxGtkTreeModelNode 
*parent_node 
= FindNode( parent 
); 
3520         wxASSERT_MSG(parent_node
, 
3521             "Did you forget a call to ItemAdded()? The parent node is unknown to the wxGtkTreeModel"); 
3523         BuildBranch( parent_node 
); 
3525         if (parent_node
->GetChildCount() == 0) 
3528         iter
->stamp 
= m_gtk_model
->stamp
; 
3529         iter
->user_data 
= (gpointer
) parent_node
->GetChildren().Item( 0 ); 
3535 gboolean 
wxDataViewCtrlInternal::iter_has_child( GtkTreeIter 
*iter 
) 
3537     if (m_wx_model
->IsVirtualListModel()) 
3539         wxDataViewVirtualListModel 
*wx_model 
= (wxDataViewVirtualListModel
*) m_wx_model
; 
3542             return (wx_model
->GetCount() > 0); 
3544         // this is a list, nodes have no children 
3550             return (m_root
->GetChildCount() > 0); 
3552         wxDataViewItem 
item( (void*) iter
->user_data 
); 
3554         bool is_container 
= m_wx_model
->IsContainer( item 
); 
3559         wxGtkTreeModelNode 
*node 
= FindNode( iter 
); 
3561             "Did you forget a call to ItemAdded()? The iterator is unknown to the wxGtkTreeModel"); 
3563         BuildBranch( node 
); 
3565         return (node
->GetChildCount() > 0); 
3569 gint 
wxDataViewCtrlInternal::iter_n_children( GtkTreeIter 
*iter 
) 
3571     if (m_wx_model
->IsVirtualListModel()) 
3573         wxDataViewVirtualListModel 
*wx_model 
= (wxDataViewVirtualListModel
*) m_wx_model
; 
3576             return (gint
) wx_model
->GetCount(); 
3583             return m_root
->GetChildCount(); 
3585         wxDataViewItem 
item( (void*) iter
->user_data 
); 
3587         if (!m_wx_model
->IsContainer( item 
)) 
3590         wxGtkTreeModelNode 
*parent_node 
= FindNode( iter 
); 
3591         wxASSERT_MSG(parent_node
, 
3592             "Did you forget a call to ItemAdded()? The parent node is unknown to the wxGtkTreeModel"); 
3594         BuildBranch( parent_node 
); 
3596         return parent_node
->GetChildCount(); 
3600 gboolean 
wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter 
*iter
, GtkTreeIter 
*parent
, gint n 
) 
3602     if (m_wx_model
->IsVirtualListModel()) 
3604         wxDataViewVirtualListModel 
*wx_model 
= (wxDataViewVirtualListModel
*) m_wx_model
; 
3612         if (n 
>= (gint
) wx_model
->GetCount()) 
3615         iter
->stamp 
= m_gtk_model
->stamp
; 
3616         // user_data is just the index +1 
3617         iter
->user_data 
= (gpointer
) (n
+1); 
3624         if (parent
) id 
= (void*) parent
->user_data
; 
3625         wxDataViewItem 
item( id 
); 
3627         if (!m_wx_model
->IsContainer( item 
)) 
3630         wxGtkTreeModelNode 
*parent_node 
= FindNode( parent 
); 
3631         wxASSERT_MSG(parent_node
, 
3632             "Did you forget a call to ItemAdded()? The parent node is unknown to the wxGtkTreeModel"); 
3634         BuildBranch( parent_node 
); 
3636         iter
->stamp 
= m_gtk_model
->stamp
; 
3637         iter
->user_data 
= parent_node
->GetChildren().Item( n 
); 
3643 gboolean 
wxDataViewCtrlInternal::iter_parent( GtkTreeIter 
*iter
, GtkTreeIter 
*child 
) 
3645     if (m_wx_model
->IsVirtualListModel()) 
3651         wxGtkTreeModelNode 
*node 
= FindParentNode( child 
); 
3655         iter
->stamp 
= m_gtk_model
->stamp
; 
3656         iter
->user_data 
= (gpointer
) node
->GetItem().GetID(); 
3662 static wxGtkTreeModelNode
* 
3663 wxDataViewCtrlInternal_FindNode( wxDataViewModel 
* model
, wxGtkTreeModelNode 
*treeNode
, const wxDataViewItem 
&item 
) 
3669     list
.DeleteContents( true ); 
3670     wxDataViewItem 
it( item 
); 
3674         wxDataViewItem 
* pItem 
= new wxDataViewItem( it 
); 
3675         list
.Insert( pItem 
); 
3676         it 
= model
->GetParent( it 
); 
3679     wxGtkTreeModelNode 
* node 
= treeNode
; 
3680     for( ItemList::compatibility_iterator n 
= list
.GetFirst(); n
; n 
= n
->GetNext() ) 
3682         if( node 
&& node
->GetNodes().GetCount() != 0 ) 
3684             int len 
= node
->GetNodes().GetCount(); 
3685             wxGtkTreeModelNodes nodes 
= node
->GetNodes(); 
3687             for( ; j 
< len
; j 
++) 
3689                 if( nodes
[j
]->GetItem() == *(n
->GetData())) 
3708 wxGtkTreeModelNode 
*wxDataViewCtrlInternal::FindNode( GtkTreeIter 
*iter 
) 
3713     wxDataViewItem 
item( (void*) iter
->user_data 
); 
3717     wxGtkTreeModelNode 
*result 
= wxDataViewCtrlInternal_FindNode( m_wx_model
, m_root
, item 
); 
3722         wxLogDebug( "Not found %p", iter->user_data ); 
3726     // TODO: remove this code 
3732 wxGtkTreeModelNode 
*wxDataViewCtrlInternal::FindNode( const wxDataViewItem 
&item 
) 
3737     wxGtkTreeModelNode 
*result 
= wxDataViewCtrlInternal_FindNode( m_wx_model
, m_root
, item 
); 
3742         wxLogDebug( "Not found %p", item.GetID() ); 
3746     // TODO: remove this code 
3752 static wxGtkTreeModelNode
* 
3753 wxDataViewCtrlInternal_FindParentNode( wxDataViewModel 
* model
, wxGtkTreeModelNode 
*treeNode
, const wxDataViewItem 
&item 
) 
3759     list
.DeleteContents( true ); 
3763     wxDataViewItem 
it( model
->GetParent( item 
) ); 
3766         wxDataViewItem 
* pItem 
= new wxDataViewItem( it 
); 
3767         list
.Insert( pItem 
); 
3768         it 
= model
->GetParent( it 
); 
3771     wxGtkTreeModelNode 
* node 
= treeNode
; 
3772     for( ItemList::compatibility_iterator n 
= list
.GetFirst(); n
; n 
= n
->GetNext() ) 
3774         if( node 
&& node
->GetNodes().GetCount() != 0 ) 
3776             int len 
= node
->GetNodes().GetCount(); 
3777             wxGtkTreeModelNodes nodes 
= node
->GetNodes(); 
3779             for( ; j 
< len
; j 
++) 
3781                 if( nodes
[j
]->GetItem() == *(n
->GetData())) 
3796     //Examine whether the node is item's parent node 
3797     int len 
= node
->GetChildCount(); 
3798     for( int i 
= 0; i 
< len 
; i 
++ ) 
3800         if( node
->GetChildren().Item( i 
) == item
.GetID() ) 
3806 wxGtkTreeModelNode 
*wxDataViewCtrlInternal::FindParentNode( GtkTreeIter 
*iter 
) 
3811     wxDataViewItem 
item( (void*) iter
->user_data 
); 
3815     return wxDataViewCtrlInternal_FindParentNode( m_wx_model
, m_root
, item 
); 
3818 wxGtkTreeModelNode 
*wxDataViewCtrlInternal::FindParentNode( const wxDataViewItem 
&item 
) 
3823     return wxDataViewCtrlInternal_FindParentNode( m_wx_model
, m_root
, item 
); 
3826 //----------------------------------------------------------------------------- 
3827 // wxDataViewCtrl signal callbacks 
3828 //----------------------------------------------------------------------------- 
3831 wxdataview_selection_changed_callback( GtkTreeSelection
* WXUNUSED(selection
), wxDataViewCtrl 
*dv 
) 
3833     if (!GTK_WIDGET_REALIZED(dv
->m_widget
)) 
3836     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED
, dv
->GetId() ); 
3837     event
.SetItem( dv
->GetSelection() ); 
3838     event
.SetModel( dv
->GetModel() ); 
3839     dv
->HandleWindowEvent( event 
); 
3843 wxdataview_row_activated_callback( GtkTreeView
* WXUNUSED(treeview
), GtkTreePath 
*path
, 
3844                                    GtkTreeViewColumn 
*WXUNUSED(column
), wxDataViewCtrl 
*dv 
) 
3846     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED
, dv
->GetId() ); 
3849     dv
->GtkGetInternal()->get_iter( &iter
, path 
); 
3850     wxDataViewItem 
item( (void*) iter
.user_data 
);; 
3851     event
.SetItem( item 
); 
3852     event
.SetModel( dv
->GetModel() ); 
3853     dv
->HandleWindowEvent( event 
); 
3857 wxdataview_test_expand_row_callback( GtkTreeView
* WXUNUSED(treeview
), GtkTreeIter
* iter
, 
3858                                      GtkTreePath 
*WXUNUSED(path
), wxDataViewCtrl 
*dv 
) 
3860     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING
, dv
->GetId() ); 
3862     wxDataViewItem 
item( (void*) iter
->user_data 
);; 
3863     event
.SetItem( item 
); 
3864     event
.SetModel( dv
->GetModel() ); 
3865     dv
->HandleWindowEvent( event 
); 
3867     return !event
.IsAllowed(); 
3871 wxdataview_row_expanded_callback( GtkTreeView
* WXUNUSED(treeview
), GtkTreeIter
* iter
, 
3872                                   GtkTreePath 
*WXUNUSED(path
), wxDataViewCtrl 
*dv 
) 
3874     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDED
, dv
->GetId() ); 
3876     wxDataViewItem 
item( (void*) iter
->user_data 
);; 
3877     event
.SetItem( item 
); 
3878     event
.SetModel( dv
->GetModel() ); 
3879     dv
->HandleWindowEvent( event 
); 
3883 wxdataview_test_collapse_row_callback( GtkTreeView
* WXUNUSED(treeview
), GtkTreeIter
* iter
, 
3884                                        GtkTreePath 
*WXUNUSED(path
), wxDataViewCtrl 
*dv 
) 
3886     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSING
, dv
->GetId() ); 
3888     wxDataViewItem 
item( (void*) iter
->user_data 
);; 
3889     event
.SetItem( item 
); 
3890     event
.SetModel( dv
->GetModel() ); 
3891     dv
->HandleWindowEvent( event 
); 
3893     return !event
.IsAllowed(); 
3897 wxdataview_row_collapsed_callback( GtkTreeView
* WXUNUSED(treeview
), GtkTreeIter
* iter
, 
3898                                    GtkTreePath 
*WXUNUSED(path
), wxDataViewCtrl 
*dv 
) 
3900     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSED
, dv
->GetId() ); 
3902     wxDataViewItem 
item( (void*) iter
->user_data 
);; 
3903     event
.SetItem( item 
); 
3904     event
.SetModel( dv
->GetModel() ); 
3905     dv
->HandleWindowEvent( event 
); 
3908 //----------------------------------------------------------------------------- 
3910 //----------------------------------------------------------------------------- 
3912 void wxDataViewCtrl::AddChildGTK(wxWindowGTK
* child
) 
3914     GtkWidget
* treeview 
= GtkGetTreeView(); 
3916     // Insert widget in GtkTreeView 
3917     if (GTK_WIDGET_REALIZED(treeview
)) 
3918         gtk_widget_set_parent_window( child
->m_widget
, 
3919           gtk_tree_view_get_bin_window( GTK_TREE_VIEW(treeview
) ) ); 
3920     gtk_widget_set_parent( child
->m_widget
, treeview 
); 
3924 void gtk_dataviewctrl_size_callback( GtkWidget 
*WXUNUSED(widget
), 
3925                                      GtkAllocation 
*WXUNUSED(gtk_alloc
), 
3926                                      wxDataViewCtrl 
*win 
) 
3928     wxWindowList::compatibility_iterator node 
= win
->GetChildren().GetFirst(); 
3931         wxWindow 
*child 
= node
->GetData(); 
3934         gtk_widget_size_request( child
->m_widget
, &req 
); 
3936         GtkAllocation alloc
; 
3937         alloc
.x 
= child
->m_x
; 
3938         alloc
.y 
= child
->m_y
; 
3939         alloc
.width 
= child
->m_width
; 
3940         alloc
.height 
= child
->m_height
; 
3941         gtk_widget_size_allocate( child
->m_widget
, &alloc 
); 
3943         node 
= node
->GetNext(); 
3948 //----------------------------------------------------------------------------- 
3949 // "motion_notify_event" 
3950 //----------------------------------------------------------------------------- 
3953 gtk_dataview_motion_notify_callback( GtkWidget 
*WXUNUSED(widget
), 
3954                                      GdkEventMotion 
*gdk_event
, 
3955                                      wxDataViewCtrl 
*dv 
) 
3957     if (gdk_event
->is_hint
) 
3961         GdkModifierType state
; 
3962         gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
3967     GtkTreePath 
*path 
= NULL
; 
3968     GtkTreeViewColumn 
*column 
= NULL
; 
3971     if (gtk_tree_view_get_path_at_pos( 
3972         GTK_TREE_VIEW(dv
->GtkGetTreeView()), 
3973         (int) gdk_event
->x
, (int) gdk_event
->y
, 
3982             dv
->GtkGetInternal()->get_iter( &iter
, path 
); 
3984             gtk_tree_path_free( path 
); 
3992 //----------------------------------------------------------------------------- 
3993 // "button_press_event" 
3994 //----------------------------------------------------------------------------- 
3997 gtk_dataview_button_press_callback( GtkWidget 
*WXUNUSED(widget
), 
3998                                     GdkEventButton 
*gdk_event
, 
3999                                     wxDataViewCtrl 
*dv 
) 
4001     if ((gdk_event
->button 
== 3) && (gdk_event
->type 
== GDK_BUTTON_PRESS
)) 
4003         GtkTreePath 
*path 
= NULL
; 
4004         GtkTreeViewColumn 
*column 
= NULL
; 
4007         if (gtk_tree_view_get_path_at_pos( 
4008             GTK_TREE_VIEW(dv
->GtkGetTreeView()), 
4009             (int) gdk_event
->x
, (int) gdk_event
->y
, 
4018                 dv
->GtkGetInternal()->get_iter( &iter
, path 
); 
4020                 wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU
, dv
->GetId() ); 
4021                 wxDataViewItem 
item( (void*) iter
.user_data 
);; 
4022                 event
.SetItem( item 
); 
4023                 event
.SetModel( dv
->GetModel() ); 
4024                 bool ret 
= dv
->HandleWindowEvent( event 
); 
4025                 gtk_tree_path_free( path 
); 
4034 IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl
, wxDataViewCtrlBase
) 
4036 wxDataViewCtrl::~wxDataViewCtrl() 
4039         GetModel()->RemoveNotifier( m_notifier 
); 
4043     // remove the model from the GtkTreeView before it gets destroyed by the 
4044     // wxDataViewCtrlBase's dtor 
4045     gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview
), NULL 
); 
4050 void wxDataViewCtrl::Init() 
4055     m_cols
.DeleteContents( true ); 
4058 bool wxDataViewCtrl::Create(wxWindow 
*parent
, wxWindowID id
, 
4059            const wxPoint
& pos
, const wxSize
& size
, 
4060            long style
, const wxValidator
& validator 
) 
4064     if (!PreCreation( parent
, pos
, size 
) || 
4065         !CreateBase( parent
, id
, pos
, size
, style
, validator 
)) 
4067         wxFAIL_MSG( wxT("wxDataViewCtrl creation failed") ); 
4071     m_widget 
= gtk_scrolled_window_new (NULL
, NULL
); 
4072     g_object_ref(m_widget
); 
4074     GTKScrolledWindowSetBorder(m_widget
, style
); 
4076     m_treeview 
= gtk_tree_view_new(); 
4077     gtk_container_add (GTK_CONTAINER (m_widget
), m_treeview
); 
4079     g_signal_connect (m_treeview
, "size_allocate", 
4080                      G_CALLBACK (gtk_dataviewctrl_size_callback
), this); 
4083     if (!gtk_check_version(2,6,0)) 
4085         bool fixed 
= (style 
& wxDV_VARIABLE_LINE_HEIGHT
) == 0; 
4086         gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview
), fixed 
); 
4090     if (style 
& wxDV_MULTIPLE
) 
4092         GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4093         gtk_tree_selection_set_mode( selection
, GTK_SELECTION_MULTIPLE 
); 
4096     gtk_tree_view_set_headers_visible( GTK_TREE_VIEW(m_treeview
), (style 
& wxDV_NO_HEADER
) == 0 ); 
4099     if (!gtk_check_version(2,10,0)) 
4101         GtkTreeViewGridLines grid 
= GTK_TREE_VIEW_GRID_LINES_NONE
; 
4103         if ((style 
& wxDV_HORIZ_RULES
) != 0 && 
4104             (style 
& wxDV_VERT_RULES
) != 0) 
4105             grid 
= GTK_TREE_VIEW_GRID_LINES_BOTH
; 
4106         else if (style 
& wxDV_VERT_RULES
) 
4107             grid 
= GTK_TREE_VIEW_GRID_LINES_VERTICAL
; 
4108         else if (style 
& wxDV_HORIZ_RULES
) 
4109             grid 
= GTK_TREE_VIEW_GRID_LINES_HORIZONTAL
; 
4111         if (grid 
!= GTK_TREE_VIEW_GRID_LINES_NONE
) 
4112             gtk_tree_view_set_grid_lines( GTK_TREE_VIEW(m_treeview
), grid 
); 
4116     gtk_tree_view_set_rules_hint( GTK_TREE_VIEW(m_treeview
), (style 
& wxDV_ROW_LINES
) != 0 ); 
4118     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_widget
), 
4119         GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
); 
4120     gtk_widget_show (m_treeview
); 
4122     m_parent
->DoAddChild( this ); 
4126     GtkEnableSelectionEvents(); 
4128     g_signal_connect_after (m_treeview
, "row-activated", 
4129                             G_CALLBACK (wxdataview_row_activated_callback
), this); 
4131     g_signal_connect (m_treeview
, "test-collapse-row", 
4132                             G_CALLBACK (wxdataview_test_collapse_row_callback
), this); 
4134     g_signal_connect_after (m_treeview
, "row-collapsed", 
4135                             G_CALLBACK (wxdataview_row_collapsed_callback
), this); 
4137     g_signal_connect (m_treeview
, "test-expand-row", 
4138                             G_CALLBACK (wxdataview_test_expand_row_callback
), this); 
4140     g_signal_connect_after (m_treeview
, "row-expanded", 
4141                             G_CALLBACK (wxdataview_row_expanded_callback
), this); 
4143     g_signal_connect (m_treeview
, "motion_notify_event", 
4144                       G_CALLBACK (gtk_dataview_motion_notify_callback
), this); 
4146     g_signal_connect (m_treeview
, "button_press_event", 
4147                       G_CALLBACK (gtk_dataview_button_press_callback
), this); 
4152 void wxDataViewCtrl::OnInternalIdle() 
4154     wxWindow::OnInternalIdle(); 
4156     unsigned int cols 
= GetColumnCount(); 
4158     for (i 
= 0; i 
< cols
; i
++) 
4160         wxDataViewColumn 
*col 
= GetColumn( i 
); 
4161         col
->OnInternalIdle(); 
4165 bool wxDataViewCtrl::AssociateModel( wxDataViewModel 
*model 
) 
4176     if (!wxDataViewCtrlBase::AssociateModel( model 
)) 
4180     if (!gtk_check_version(2,6,0)) 
4182         bool fixed 
= (((GetWindowStyle() & wxDV_VARIABLE_LINE_HEIGHT
) == 0) || (model
->IsVirtualListModel())); 
4183         gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview
), fixed 
); 
4187     GtkWxTreeModel 
*gtk_model 
= wxgtk_tree_model_new(); 
4188     m_internal 
= new wxDataViewCtrlInternal( this, model
, gtk_model 
); 
4189     gtk_model
->internal 
= m_internal
; 
4191     m_notifier 
= new wxGtkDataViewModelNotifier( gtk_model
, model
, this ); 
4193     model
->AddNotifier( m_notifier 
); 
4195     gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview
), GTK_TREE_MODEL(gtk_model
) ); 
4197     // unref in wxDataViewCtrlInternal 
4198     // g_object_unref( gtk_model ); 
4203 bool wxDataViewCtrl::EnableDragSource( const wxDataFormat 
&format 
) 
4205     return m_internal
->EnableDragSource( format 
); 
4208 bool wxDataViewCtrl::EnableDropTarget( const wxDataFormat 
&format 
) 
4210     return m_internal
->EnableDropTarget( format 
); 
4213 bool wxDataViewCtrl::AppendColumn( wxDataViewColumn 
*col 
) 
4215     if (!wxDataViewCtrlBase::AppendColumn(col
)) 
4218     m_cols
.Append( col 
); 
4221     if (!gtk_check_version(2,6,0)) 
4223         if (gtk_tree_view_column_get_sizing( GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()) ) != 
4224                GTK_TREE_VIEW_COLUMN_FIXED
) 
4225            gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview
), FALSE 
); 
4229     gtk_tree_view_append_column( GTK_TREE_VIEW(m_treeview
), 
4230                                  GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()) ); 
4235 bool wxDataViewCtrl::PrependColumn( wxDataViewColumn 
*col 
) 
4237     if (!wxDataViewCtrlBase::PrependColumn(col
)) 
4240     m_cols
.Insert( col 
); 
4243     if (!gtk_check_version(2,6,0)) 
4245         if (gtk_tree_view_column_get_sizing( GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()) ) != 
4246                GTK_TREE_VIEW_COLUMN_FIXED
) 
4247            gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview
), FALSE 
); 
4251     gtk_tree_view_insert_column( GTK_TREE_VIEW(m_treeview
), 
4252                                  GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()), 0 ); 
4257 bool wxDataViewCtrl::InsertColumn( unsigned int pos
, wxDataViewColumn 
*col 
) 
4259     if (!wxDataViewCtrlBase::InsertColumn(pos
,col
)) 
4262     m_cols
.Insert( pos
, col 
); 
4265     if (!gtk_check_version(2,6,0)) 
4267         if (gtk_tree_view_column_get_sizing( GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()) ) != 
4268                GTK_TREE_VIEW_COLUMN_FIXED
) 
4269            gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview
), FALSE 
); 
4273     gtk_tree_view_insert_column( GTK_TREE_VIEW(m_treeview
), 
4274                                  GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()), pos 
); 
4279 unsigned int wxDataViewCtrl::GetColumnCount() const 
4281     return m_cols
.GetCount(); 
4284 wxDataViewColumn
* wxDataViewCtrl::GetColumn( unsigned int pos 
) const 
4286     GtkTreeViewColumn 
*gtk_col 
= gtk_tree_view_get_column( GTK_TREE_VIEW(m_treeview
), pos 
); 
4290     wxDataViewColumnList::const_iterator iter
; 
4291     for (iter 
= m_cols
.begin(); iter 
!= m_cols
.end(); ++iter
) 
4293         wxDataViewColumn 
*col 
= *iter
; 
4294         if (GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()) == gtk_col
) 
4303 bool wxDataViewCtrl::DeleteColumn( wxDataViewColumn 
*column 
) 
4305     gtk_tree_view_remove_column( GTK_TREE_VIEW(m_treeview
), 
4306                                  GTK_TREE_VIEW_COLUMN(column
->GetGtkHandle()) ); 
4308     m_cols
.DeleteObject( column 
); 
4313 bool wxDataViewCtrl::ClearColumns() 
4315     wxDataViewColumnList::iterator iter
; 
4316     for (iter 
= m_cols
.begin(); iter 
!= m_cols
.end(); ++iter
) 
4318         wxDataViewColumn 
*col 
= *iter
; 
4319         gtk_tree_view_remove_column( GTK_TREE_VIEW(m_treeview
), 
4320                                      GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()) ); 
4328 int wxDataViewCtrl::GetColumnPosition( const wxDataViewColumn 
*column 
) const 
4330     GtkTreeViewColumn 
*gtk_column 
= GTK_TREE_VIEW_COLUMN(column
->GetConstGtkHandle()); 
4332     GList 
*list 
= gtk_tree_view_get_columns( GTK_TREE_VIEW(m_treeview
) ); 
4334     gint pos 
= g_list_index( list
, (gconstpointer
)  gtk_column 
); 
4336     g_list_free( list 
); 
4341 wxDataViewColumn 
*wxDataViewCtrl::GetSortingColumn() const 
4343     return m_internal
->GetDataViewSortColumn(); 
4346 void wxDataViewCtrl::Expand( const wxDataViewItem 
& item 
) 
4349     iter
.user_data 
= item
.GetID(); 
4350     GtkTreePath 
*path 
= m_internal
->get_path( &iter 
); 
4351     gtk_tree_view_expand_row( GTK_TREE_VIEW(m_treeview
), path
, false ); 
4352     gtk_tree_path_free( path 
); 
4355 void wxDataViewCtrl::Collapse( const wxDataViewItem 
& item 
) 
4358     iter
.user_data 
= item
.GetID(); 
4359     GtkTreePath 
*path 
= m_internal
->get_path( &iter 
); 
4360     gtk_tree_view_collapse_row( GTK_TREE_VIEW(m_treeview
), path 
); 
4361     gtk_tree_path_free( path 
); 
4364 bool wxDataViewCtrl::IsExpanded( const wxDataViewItem 
& item 
) const 
4367     iter
.user_data 
= item
.GetID(); 
4368     GtkTreePath 
*path 
= m_internal
->get_path( &iter 
); 
4369     bool res 
= gtk_tree_view_row_expanded( GTK_TREE_VIEW(m_treeview
), path 
); 
4370     gtk_tree_path_free( path 
); 
4375 wxDataViewItem 
wxDataViewCtrl::GetSelection() const 
4377     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4379     if (m_windowStyle 
& wxDV_MULTIPLE
) 
4381         // Report the first one 
4382         GtkTreeModel 
*model
; 
4383         GList 
*list 
= gtk_tree_selection_get_selected_rows( selection
, &model 
); 
4387             GtkTreePath 
*path 
= (GtkTreePath
*) list
->data
; 
4389             m_internal
->get_iter( &iter
, path 
); 
4392             g_list_foreach( list
, (GFunc
) gtk_tree_path_free
, NULL 
); 
4393             g_list_free( list 
); 
4395             return wxDataViewItem( (void*) iter
.user_data 
); 
4401         if (gtk_tree_selection_get_selected( selection
, NULL
, &iter 
)) 
4403             wxDataViewItem 
item( (void*) iter
.user_data 
); 
4408     return wxDataViewItem(0); 
4411 int wxDataViewCtrl::GetSelections( wxDataViewItemArray 
& sel 
) const 
4415     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4416     if (HasFlag(wxDV_MULTIPLE
)) 
4418         GtkTreeModel 
*model
; 
4419         GList 
*list 
= gtk_tree_selection_get_selected_rows( selection
, &model 
); 
4424             GtkTreePath 
*path 
= (GtkTreePath
*) list
->data
; 
4427             m_internal
->get_iter( &iter
, path 
); 
4429             sel
.Add( wxDataViewItem( (void*) iter
.user_data 
) ); 
4431             list 
= g_list_next( list 
); 
4436         g_list_foreach( list
, (GFunc
) gtk_tree_path_free
, NULL 
); 
4437         g_list_free( list 
); 
4443         GtkTreeModel 
*model
; 
4445         gboolean has_selection 
= gtk_tree_selection_get_selected( selection
, &model
, &iter 
); 
4448             sel
.Add( wxDataViewItem( (void*) iter
.user_data
) ); 
4456 void wxDataViewCtrl::SetSelections( const wxDataViewItemArray 
& sel 
) 
4458     GtkDisableSelectionEvents(); 
4460     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4462     gtk_tree_selection_unselect_all( selection 
); 
4464     wxDataViewItem last_parent
; 
4467     for (i 
= 0; i 
< sel
.GetCount(); i
++) 
4469         wxDataViewItem item 
= sel
[i
]; 
4470         wxDataViewItem parent 
= GetModel()->GetParent( item 
); 
4473             if (parent 
!= last_parent
) 
4474                 ExpandAncestors(item
); 
4476         last_parent 
= parent
; 
4479         iter
.stamp 
= m_internal
->GetGtkModel()->stamp
; 
4480         iter
.user_data 
= (gpointer
) item
.GetID(); 
4481         gtk_tree_selection_select_iter( selection
, &iter 
); 
4484     GtkEnableSelectionEvents(); 
4487 void wxDataViewCtrl::Select( const wxDataViewItem 
& item 
) 
4489     ExpandAncestors(item
); 
4491     GtkDisableSelectionEvents(); 
4493     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4496     iter
.stamp 
= m_internal
->GetGtkModel()->stamp
; 
4497     iter
.user_data 
= (gpointer
) item
.GetID(); 
4498     gtk_tree_selection_select_iter( selection
, &iter 
); 
4500     GtkEnableSelectionEvents(); 
4503 void wxDataViewCtrl::Unselect( const wxDataViewItem 
& item 
) 
4505     GtkDisableSelectionEvents(); 
4507     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4510     iter
.stamp 
= m_internal
->GetGtkModel()->stamp
; 
4511     iter
.user_data 
= (gpointer
) item
.GetID(); 
4512     gtk_tree_selection_unselect_iter( selection
, &iter 
); 
4514     GtkEnableSelectionEvents(); 
4517 bool wxDataViewCtrl::IsSelected( const wxDataViewItem 
& item 
) const 
4519     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4522     iter
.stamp 
= m_internal
->GetGtkModel()->stamp
; 
4523     iter
.user_data 
= (gpointer
) item
.GetID(); 
4525     return gtk_tree_selection_iter_is_selected( selection
, &iter 
); 
4528 void wxDataViewCtrl::SelectAll() 
4530     GtkDisableSelectionEvents(); 
4532     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4534     gtk_tree_selection_select_all( selection 
); 
4536     GtkEnableSelectionEvents(); 
4539 void wxDataViewCtrl::UnselectAll() 
4541     GtkDisableSelectionEvents(); 
4543     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4545     gtk_tree_selection_unselect_all( selection 
); 
4547     GtkEnableSelectionEvents(); 
4550 void wxDataViewCtrl::EnsureVisible(const wxDataViewItem
& item
, 
4551                                    const wxDataViewColumn 
*WXUNUSED(column
)) 
4553     ExpandAncestors(item
); 
4556     iter
.user_data 
= (gpointer
) item
.GetID(); 
4557     GtkTreePath 
*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     gtk_tree_path_free( path 
); 
4562 void wxDataViewCtrl::HitTest(const wxPoint
& WXUNUSED(point
), 
4563                              wxDataViewItem
& item
, 
4564                              wxDataViewColumn 
*& column
) const 
4566     item 
= wxDataViewItem(0); 
4571 wxDataViewCtrl::GetItemRect(const wxDataViewItem
& WXUNUSED(item
), 
4572                             const wxDataViewColumn 
*WXUNUSED(column
)) const 
4577 void wxDataViewCtrl::DoSetExpanderColumn() 
4579     gtk_tree_view_set_expander_column( GTK_TREE_VIEW(m_treeview
), 
4580         GTK_TREE_VIEW_COLUMN( GetExpanderColumn()->GetGtkHandle() ) ); 
4583 void wxDataViewCtrl::DoSetIndent() 
4587 void wxDataViewCtrl::GtkDisableSelectionEvents() 
4589     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4590     g_signal_handlers_disconnect_by_func( selection
, 
4591                             (gpointer
) (wxdataview_selection_changed_callback
), this); 
4594 void wxDataViewCtrl::GtkEnableSelectionEvents() 
4596     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4597     g_signal_connect_after (selection
, "changed", 
4598                             G_CALLBACK (wxdataview_selection_changed_callback
), this); 
4601 // ---------------------------------------------------------------------------- 
4602 // visual attributes stuff 
4603 // ---------------------------------------------------------------------------- 
4607 wxDataViewCtrl::GetClassDefaultAttributes(wxWindowVariant 
WXUNUSED(variant
)) 
4609     return GetDefaultAttributesFromGTKWidget(gtk_tree_view_new
); 
4612 void wxDataViewCtrl::DoApplyWidgetStyle(GtkRcStyle 
*style
) 
4614     wxDataViewCtrlBase::DoApplyWidgetStyle(style
); 
4615     gtk_widget_modify_style(m_treeview
, style
); 
4618 #endif // !wxUSE_GENERICDATAVIEWCTRL 
4620 #endif // wxUSE_DATAVIEWCTRL