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" 
  25     #include "wx/settings.h" 
  26     #include "wx/dataobj.h" 
  30 #include "wx/stockitem.h" 
  31 #include "wx/calctrl.h" 
  32 #include "wx/popupwin.h" 
  33 #include "wx/listimpl.cpp" 
  35 #include "wx/gtk/private.h" 
  36 #include "wx/gtk/dc.h" 
  37 #include "wx/gtk/dcclient.h" 
  39 //----------------------------------------------------------------------------- 
  40 //----------------------------------------------------------------------------- 
  42 class wxDataViewCtrlInternal
; 
  44 wxDataViewCtrlInternal 
*g_internal 
= NULL
; 
  46 class wxGtkTreeModelNode
; 
  49 typedef struct _GtkWxTreeModel       GtkWxTreeModel
; 
  52 //----------------------------------------------------------------------------- 
  53 // wxDataViewCtrlInternal 
  54 //----------------------------------------------------------------------------- 
  56 WX_DECLARE_LIST(wxDataViewItem
, ItemList
); 
  57 WX_DEFINE_LIST(ItemList
) 
  59 class wxDataViewCtrlInternal
 
  62     wxDataViewCtrlInternal( wxDataViewCtrl 
*owner
, wxDataViewModel 
*wx_model
, GtkWxTreeModel 
*gtk_model 
); 
  63     ~wxDataViewCtrlInternal(); 
  66     GtkTreeModelFlags 
get_flags(); 
  67     gboolean 
get_iter( GtkTreeIter 
*iter
, GtkTreePath 
*path 
); 
  68     GtkTreePath 
*get_path( GtkTreeIter 
*iter
); 
  69     gboolean 
iter_next( GtkTreeIter 
*iter 
); 
  70     gboolean 
iter_children( GtkTreeIter 
*iter
, GtkTreeIter 
*parent
); 
  71     gboolean 
iter_has_child( GtkTreeIter 
*iter 
); 
  72     gint 
iter_n_children( GtkTreeIter 
*iter 
); 
  73     gboolean 
iter_nth_child( GtkTreeIter 
*iter
, GtkTreeIter 
*parent
, gint n 
); 
  74     gboolean 
iter_parent( GtkTreeIter 
*iter
, GtkTreeIter 
*child 
); 
  78     bool EnableDragSource( const wxDataFormat 
&format 
); 
  80     gboolean 
row_draggable( GtkTreeDragSource 
*drag_source
, GtkTreePath 
*path 
); 
  81     gboolean 
drag_data_delete( GtkTreeDragSource 
*drag_source
, GtkTreePath
* path 
); 
  82     gboolean 
drag_data_get( GtkTreeDragSource 
*drag_source
, GtkTreePath 
*path
, 
  83         GtkSelectionData 
*selection_data 
); 
  84     gboolean 
drag_data_received( GtkTreeDragDest 
*drag_dest
, GtkTreePath 
*dest
, 
  85         GtkSelectionData 
*selection_data 
); 
  86     gboolean 
row_drop_possible( GtkTreeDragDest 
*drag_dest
, GtkTreePath 
*dest_path
, 
  87         GtkSelectionData 
*selection_data 
); 
  89     // notifactions from wxDataViewModel 
  90     bool ItemAdded( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
); 
  91     bool ItemDeleted( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
); 
  92     bool ItemChanged( const wxDataViewItem 
&item 
); 
  93     bool ValueChanged( const wxDataViewItem 
&item
, unsigned int col 
); 
  98     void SetSortOrder( GtkSortType sort_order 
) { m_sort_order 
= sort_order
; } 
  99     GtkSortType 
GetSortOrder()                  { return m_sort_order
; } 
 101     void SetSortColumn( int column 
)            { m_sort_column 
= column
; } 
 102     int GetSortColumn()                         { return m_sort_column
; } 
 104     void SetDataViewSortColumn( wxDataViewColumn 
*column 
) { m_dataview_sort_column 
= column
; } 
 105     wxDataViewColumn 
*GetDataViewSortColumn()   { return m_dataview_sort_column
; } 
 107     bool IsSorted()                             { return (m_sort_column 
>= 0); } 
 110     wxDataViewModel
* GetDataViewModel() { return m_wx_model
; } 
 111     wxDataViewCtrl
* GetOwner()          { return m_owner
; } 
 112     GtkWxTreeModel
* GetGtkModel()       { return m_gtk_model
; } 
 116     wxGtkTreeModelNode 
*FindNode( const wxDataViewItem 
&item 
); 
 117     wxGtkTreeModelNode 
*FindNode( GtkTreeIter 
*iter 
); 
 118     wxGtkTreeModelNode 
*FindParentNode( const wxDataViewItem 
&item 
); 
 119     wxGtkTreeModelNode 
*FindParentNode( GtkTreeIter 
*iter 
); 
 120     void BuildBranch( wxGtkTreeModelNode 
*branch 
); 
 123     wxGtkTreeModelNode   
*m_root
; 
 124     wxDataViewModel      
*m_wx_model
; 
 125     GtkWxTreeModel       
*m_gtk_model
; 
 126     wxDataViewCtrl       
*m_owner
; 
 127     GtkSortType           m_sort_order
; 
 128     wxDataViewColumn     
*m_dataview_sort_column
; 
 130     GtkTargetEntry        m_dragSourceTargetEntry
; 
 131     wxCharBuffer          m_dragSourceTargetEntryTarget
; 
 132     wxDataObject         
*m_dragDataObject
; 
 133     wxDataObject         
*m_dropDataObject
; 
 137 //----------------------------------------------------------------------------- 
 138 // wxGtkTreeModelNode 
 139 //----------------------------------------------------------------------------- 
 141 int LINKAGEMODE 
wxGtkTreeModelChildCmp( void** id1
, void** id2 
) 
 143     int ret 
= g_internal
->GetDataViewModel()->Compare( *id1
, *id2
, 
 144         g_internal
->GetSortColumn(), (g_internal
->GetSortOrder() == GTK_SORT_ASCENDING
) ); 
 149 WX_DEFINE_ARRAY_PTR( wxGtkTreeModelNode
*, wxGtkTreeModelNodes 
); 
 150 WX_DEFINE_ARRAY_PTR( void*, wxGtkTreeModelChildren 
); 
 152 class wxGtkTreeModelNode
 
 155     wxGtkTreeModelNode( wxGtkTreeModelNode
* parent
, const wxDataViewItem 
&item
, 
 156       wxDataViewCtrlInternal 
*internal 
) 
 160         m_internal 
= internal
; 
 163     ~wxGtkTreeModelNode() 
 165         size_t count 
= m_nodes
.GetCount(); 
 167         for (i 
= 0; i 
< count
; i
++) 
 169             wxGtkTreeModelNode 
*child 
= m_nodes
.Item( i 
); 
 174     unsigned int AddNode( wxGtkTreeModelNode
* child 
) 
 176             m_nodes
.Add( child 
); 
 178             void *id 
= child
->GetItem().GetID(); 
 180             m_children
.Add( id 
); 
 182             if (m_internal
->IsSorted() || m_internal
->GetDataViewModel()->HasDefaultCompare()) 
 184                 g_internal 
= m_internal
; 
 185                 m_children
.Sort( &wxGtkTreeModelChildCmp 
); 
 186                 return m_children
.Index( id 
); 
 189             return m_children
.GetCount()-1; 
 192     unsigned int AddLeave( void* id 
) 
 194             m_children
.Add( id 
); 
 196             if (m_internal
->IsSorted() || m_internal
->GetDataViewModel()->HasDefaultCompare()) 
 198                 g_internal 
= m_internal
; 
 199                 m_children
.Sort( &wxGtkTreeModelChildCmp 
); 
 200                 return m_children
.Index( id 
); 
 203             return m_children
.GetCount()-1; 
 206     void DeleteChild( void* id 
) 
 208             m_children
.Remove( id 
); 
 210             unsigned int count 
= m_nodes
.GetCount(); 
 212             for (pos 
= 0; pos 
< count
; pos
++) 
 214                 wxGtkTreeModelNode 
*node 
= m_nodes
.Item( pos 
); 
 215                 if (node
->GetItem().GetID() == id
) 
 217                     m_nodes
.RemoveAt( pos 
); 
 225     wxGtkTreeModelNode
* GetParent() 
 227     wxGtkTreeModelNodes 
&GetNodes() 
 229     wxGtkTreeModelChildren 
&GetChildren() 
 230         { return m_children
; } 
 232     unsigned int GetChildCount() { return m_children
.GetCount(); } 
 233     unsigned int GetNodesCount() { return m_nodes
.GetCount(); } 
 235     wxDataViewItem 
&GetItem() { return m_item
; } 
 236     wxDataViewCtrlInternal 
*GetInternal() { return m_internal
; } 
 241     wxGtkTreeModelNode         
*m_parent
; 
 242     wxGtkTreeModelNodes         m_nodes
; 
 243     wxGtkTreeModelChildren      m_children
; 
 244     wxDataViewItem              m_item
; 
 245     wxDataViewCtrlInternal     
*m_internal
; 
 249 //----------------------------------------------------------------------------- 
 251 //----------------------------------------------------------------------------- 
 253 extern bool   g_blockEventsOnDrag
; 
 255 //----------------------------------------------------------------------------- 
 256 // define new GTK+ class wxGtkTreeModel 
 257 //----------------------------------------------------------------------------- 
 261 #define GTK_TYPE_WX_TREE_MODEL               (gtk_wx_tree_model_get_type ()) 
 262 #define GTK_WX_TREE_MODEL(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModel)) 
 263 #define GTK_WX_TREE_MODEL_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModelClass)) 
 264 #define GTK_IS_WX_TREE_MODEL(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_TREE_MODEL)) 
 265 #define GTK_IS_WX_TREE_MODEL_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_TREE_MODEL)) 
 266 #define GTK_WX_TREE_MODEL_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModelClass)) 
 268 GType         
gtk_wx_tree_model_get_type         (void); 
 270 typedef struct _GtkWxTreeModelClass  GtkWxTreeModelClass
; 
 272 struct _GtkWxTreeModel
 
 278   wxDataViewCtrlInternal 
*internal
; 
 281 struct _GtkWxTreeModelClass
 
 283   GObjectClass list_parent_class
; 
 286 static GtkWxTreeModel 
*wxgtk_tree_model_new          (void); 
 287 static void         wxgtk_tree_model_init            (GtkWxTreeModel       
*tree_model
); 
 288 static void         wxgtk_tree_model_class_init      (GtkWxTreeModelClass  
*klass
); 
 290 static void         wxgtk_tree_model_tree_model_init (GtkTreeModelIface       
*iface
); 
 291 static void         wxgtk_tree_model_sortable_init   (GtkTreeSortableIface    
*iface
); 
 292 static void         wxgtk_tree_model_drag_source_init(GtkTreeDragSourceIface  
*iface
); 
 293 static void         wxgtk_tree_model_drag_dest_init  (GtkTreeDragDestIface    
*iface
); 
 295 static void         wxgtk_tree_model_finalize        (GObject           
*object
); 
 296 static GtkTreeModelFlags 
wxgtk_tree_model_get_flags  (GtkTreeModel      
*tree_model
); 
 297 static gint         
wxgtk_tree_model_get_n_columns   (GtkTreeModel      
*tree_model
); 
 298 static GType        
wxgtk_tree_model_get_column_type (GtkTreeModel      
*tree_model
, 
 300 static gboolean     
wxgtk_tree_model_get_iter        (GtkTreeModel      
*tree_model
, 
 303 static GtkTreePath 
*wxgtk_tree_model_get_path        (GtkTreeModel      
*tree_model
, 
 305 static void         wxgtk_tree_model_get_value       (GtkTreeModel      
*tree_model
, 
 309 static gboolean     
wxgtk_tree_model_iter_next       (GtkTreeModel      
*tree_model
, 
 311 static gboolean     
wxgtk_tree_model_iter_children   (GtkTreeModel      
*tree_model
, 
 313                                                       GtkTreeIter       
*parent
); 
 314 static gboolean     
wxgtk_tree_model_iter_has_child  (GtkTreeModel      
*tree_model
, 
 316 static gint         
wxgtk_tree_model_iter_n_children (GtkTreeModel      
*tree_model
, 
 318 static gboolean     
wxgtk_tree_model_iter_nth_child  (GtkTreeModel      
*tree_model
, 
 322 static gboolean     
wxgtk_tree_model_iter_parent     (GtkTreeModel      
*tree_model
, 
 327 static gboolean 
wxgtk_tree_model_get_sort_column_id    (GtkTreeSortable       
*sortable
, 
 328                                                         gint                  
*sort_column_id
, 
 330 static void     wxgtk_tree_model_set_sort_column_id    (GtkTreeSortable       
*sortable
, 
 333 static void     wxgtk_tree_model_set_sort_func         (GtkTreeSortable       
*sortable
, 
 335                                                         GtkTreeIterCompareFunc func
, 
 337                                                         GtkDestroyNotify       destroy
); 
 338 static void     wxgtk_tree_model_set_default_sort_func (GtkTreeSortable       
*sortable
, 
 339                                                         GtkTreeIterCompareFunc func
, 
 341                                                         GtkDestroyNotify       destroy
); 
 342 static gboolean 
wxgtk_tree_model_has_default_sort_func (GtkTreeSortable       
*sortable
); 
 345 static gboolean 
wxgtk_tree_model_row_draggable         (GtkTreeDragSource     
*drag_source
, 
 347 static gboolean 
wxgtk_tree_model_drag_data_delete      (GtkTreeDragSource     
*drag_source
, 
 349 static gboolean 
wxgtk_tree_model_drag_data_get         (GtkTreeDragSource     
*drag_source
, 
 351                                                         GtkSelectionData      
*selection_data
); 
 352 static gboolean 
wxgtk_tree_model_drag_data_received    (GtkTreeDragDest       
*drag_dest
, 
 354                                                         GtkSelectionData      
*selection_data
); 
 355 static gboolean 
wxgtk_tree_model_row_drop_possible     (GtkTreeDragDest       
*drag_dest
, 
 356                                                         GtkTreePath           
*dest_path
, 
 357                                                         GtkSelectionData      
*selection_data
); 
 360 static GObjectClass 
*list_parent_class 
= NULL
; 
 363 gtk_wx_tree_model_get_type (void) 
 365     static GType tree_model_type 
= 0; 
 367     if (!tree_model_type
) 
 369         const GTypeInfo tree_model_info 
= 
 371             sizeof (GtkWxTreeModelClass
), 
 372             NULL
,   /* base_init */ 
 373             NULL
,   /* base_finalize */ 
 374             (GClassInitFunc
) wxgtk_tree_model_class_init
, 
 375             NULL
,   /* class_finalize */ 
 376             NULL
,   /* class_data */ 
 377             sizeof (GtkWxTreeModel
), 
 379             (GInstanceInitFunc
) wxgtk_tree_model_init
, 
 382         static const GInterfaceInfo tree_model_iface_info 
= 
 384             (GInterfaceInitFunc
) wxgtk_tree_model_tree_model_init
, 
 389         static const GInterfaceInfo sortable_iface_info 
= 
 391             (GInterfaceInitFunc
) wxgtk_tree_model_sortable_init
, 
 396         static const GInterfaceInfo drag_source_iface_info 
= 
 398             (GInterfaceInitFunc
) wxgtk_tree_model_drag_source_init
, 
 403         static const GInterfaceInfo drag_dest_iface_info 
= 
 405             (GInterfaceInitFunc
) wxgtk_tree_model_drag_dest_init
, 
 410         tree_model_type 
= g_type_register_static (G_TYPE_OBJECT
, "GtkWxTreeModel", 
 411                                                 &tree_model_info
, (GTypeFlags
)0 ); 
 413         g_type_add_interface_static (tree_model_type
, 
 415                                      &tree_model_iface_info
); 
 416         g_type_add_interface_static (tree_model_type
, 
 417                                      GTK_TYPE_TREE_SORTABLE
, 
 418                                      &sortable_iface_info
); 
 419         g_type_add_interface_static (tree_model_type
, 
 420                                      GTK_TYPE_TREE_DRAG_DEST
, 
 421                                      &drag_dest_iface_info
); 
 422         g_type_add_interface_static (tree_model_type
, 
 423                                      GTK_TYPE_TREE_DRAG_SOURCE
, 
 424                                      &drag_source_iface_info
); 
 427     return tree_model_type
; 
 430 static GtkWxTreeModel 
* 
 431 wxgtk_tree_model_new(void) 
 433     GtkWxTreeModel 
*retval 
= (GtkWxTreeModel 
*) g_object_new (GTK_TYPE_WX_TREE_MODEL
, NULL
); 
 438 wxgtk_tree_model_class_init (GtkWxTreeModelClass 
*klass
) 
 440     list_parent_class 
= (GObjectClass
*) g_type_class_peek_parent (klass
); 
 441     GObjectClass 
*object_class 
= (GObjectClass
*) klass
; 
 442     object_class
->finalize 
= wxgtk_tree_model_finalize
; 
 446 wxgtk_tree_model_tree_model_init (GtkTreeModelIface 
*iface
) 
 448     iface
->get_flags 
= wxgtk_tree_model_get_flags
; 
 449     iface
->get_n_columns 
= wxgtk_tree_model_get_n_columns
; 
 450     iface
->get_column_type 
= wxgtk_tree_model_get_column_type
; 
 451     iface
->get_iter 
= wxgtk_tree_model_get_iter
; 
 452     iface
->get_path 
= wxgtk_tree_model_get_path
; 
 453     iface
->get_value 
= wxgtk_tree_model_get_value
; 
 454     iface
->iter_next 
= wxgtk_tree_model_iter_next
; 
 455     iface
->iter_children 
= wxgtk_tree_model_iter_children
; 
 456     iface
->iter_has_child 
= wxgtk_tree_model_iter_has_child
; 
 457     iface
->iter_n_children 
= wxgtk_tree_model_iter_n_children
; 
 458     iface
->iter_nth_child 
= wxgtk_tree_model_iter_nth_child
; 
 459     iface
->iter_parent 
= wxgtk_tree_model_iter_parent
; 
 463 wxgtk_tree_model_sortable_init (GtkTreeSortableIface 
*iface
) 
 465     iface
->get_sort_column_id 
= wxgtk_tree_model_get_sort_column_id
; 
 466     iface
->set_sort_column_id 
= wxgtk_tree_model_set_sort_column_id
; 
 467     iface
->set_sort_func 
= wxgtk_tree_model_set_sort_func
; 
 468     iface
->set_default_sort_func 
= wxgtk_tree_model_set_default_sort_func
; 
 469     iface
->has_default_sort_func 
= wxgtk_tree_model_has_default_sort_func
; 
 473 wxgtk_tree_model_drag_source_init(GtkTreeDragSourceIface  
*iface
) 
 475     iface
->row_draggable 
= wxgtk_tree_model_row_draggable
; 
 476     iface
->drag_data_delete 
= wxgtk_tree_model_drag_data_delete
; 
 477     iface
->drag_data_get 
= wxgtk_tree_model_drag_data_get
; 
 481 wxgtk_tree_model_drag_dest_init  (GtkTreeDragDestIface    
*iface
) 
 483     iface
->drag_data_received 
= wxgtk_tree_model_drag_data_received
; 
 484     iface
->row_drop_possible 
= wxgtk_tree_model_row_drop_possible
; 
 488 wxgtk_tree_model_init (GtkWxTreeModel 
*tree_model
) 
 490     tree_model
->internal 
= NULL
; 
 491     tree_model
->stamp 
= g_random_int(); 
 495 wxgtk_tree_model_finalize (GObject 
*object
) 
 498     (* list_parent_class
->finalize
) (object
); 
 503 //----------------------------------------------------------------------------- 
 504 // implement callbacks from wxGtkTreeModel class by letting 
 505 // them call the methods of wxWidgets' wxDataViewModel 
 506 //----------------------------------------------------------------------------- 
 508 static GtkTreeModelFlags
 
 509 wxgtk_tree_model_get_flags (GtkTreeModel 
*tree_model
) 
 511     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 512     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), (GtkTreeModelFlags
)0 ); 
 514     return wxtree_model
->internal
->get_flags(); 
 518 wxgtk_tree_model_get_n_columns (GtkTreeModel 
*tree_model
) 
 520     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 521     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), 0); 
 523     return wxtree_model
->internal
->GetDataViewModel()->GetColumnCount(); 
 527 wxgtk_tree_model_get_column_type (GtkTreeModel 
*tree_model
, 
 530     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 531     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), G_TYPE_INVALID
); 
 533     GType gtype 
= G_TYPE_INVALID
; 
 535     wxString wxtype 
= wxtree_model
->internal
->GetDataViewModel()->GetColumnType( (unsigned int) index 
); 
 537     wxPrintf( "get_column_type %s\n", wxtype 
); 
 539     if (wxtype 
== wxT("string")) 
 540         gtype 
= G_TYPE_STRING
; 
 543         gtype 
= G_TYPE_STRING
; 
 544         // wxFAIL_MSG( _T("non-string columns not supported yet") ); 
 551 wxgtk_tree_model_get_iter (GtkTreeModel 
*tree_model
, 
 555     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 556     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 557     g_return_val_if_fail (gtk_tree_path_get_depth (path
) > 0, FALSE
); 
 559     return wxtree_model
->internal
->get_iter( iter
, path 
); 
 563 wxgtk_tree_model_get_path (GtkTreeModel 
*tree_model
, 
 566     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 567     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), NULL
); 
 568     g_return_val_if_fail (iter
->stamp 
== GTK_WX_TREE_MODEL (wxtree_model
)->stamp
, NULL
); 
 570     return wxtree_model
->internal
->get_path( iter 
); 
 574 wxgtk_tree_model_get_value (GtkTreeModel 
*tree_model
, 
 579     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 580     g_return_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
) ); 
 582     wxDataViewModel 
*model 
= wxtree_model
->internal
->GetDataViewModel(); 
 583     wxString mtype 
= model
->GetColumnType( (unsigned int) column 
); 
 584     if (mtype 
== wxT("string")) 
 587         g_value_init( value
, G_TYPE_STRING 
); 
 588         wxDataViewItem 
item( (void*) iter
->user_data 
); 
 589         model
->GetValue( variant
, item
, (unsigned int) column 
); 
 591         g_value_set_string( value
, variant
.GetString().utf8_str() ); 
 595         wxFAIL_MSG( _T("non-string columns not supported yet") ); 
 600 wxgtk_tree_model_iter_next (GtkTreeModel  
*tree_model
, 
 603     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 605     if (wxtree_model
->stamp 
!= iter
->stamp
) 
 606        wxPrintf( "crash\n" ); 
 608     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 609     g_return_val_if_fail (wxtree_model
->stamp 
== iter
->stamp
, FALSE
); 
 611     return wxtree_model
->internal
->iter_next( iter 
); 
 615 wxgtk_tree_model_iter_children (GtkTreeModel 
*tree_model
, 
 619     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 620     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 621     g_return_val_if_fail (wxtree_model
->stamp 
== parent
->stamp
, FALSE
); 
 623     return wxtree_model
->internal
->iter_children( iter
, parent 
); 
 627 wxgtk_tree_model_iter_has_child (GtkTreeModel 
*tree_model
, 
 630     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 631     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 632     g_return_val_if_fail (wxtree_model
->stamp 
== iter
->stamp
, FALSE
); 
 634     return wxtree_model
->internal
->iter_has_child( iter 
); 
 638 wxgtk_tree_model_iter_n_children (GtkTreeModel 
*tree_model
, 
 641     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 642     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 643     g_return_val_if_fail (wxtree_model
->stamp 
== iter
->stamp
, 0); 
 645     return wxtree_model
->internal
->iter_n_children( iter 
); 
 649 wxgtk_tree_model_iter_nth_child (GtkTreeModel 
*tree_model
, 
 654     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 655     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 657     return wxtree_model
->internal
->iter_nth_child( iter
, parent
, n 
); 
 661 wxgtk_tree_model_iter_parent (GtkTreeModel 
*tree_model
, 
 665     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 666     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 667     g_return_val_if_fail (wxtree_model
->stamp 
== child
->stamp
, FALSE
); 
 669     return wxtree_model
->internal
->iter_parent( iter
, child 
); 
 672 /* drag'n'drop iface */ 
 674 wxgtk_tree_model_row_draggable (GtkTreeDragSource 
*drag_source
, 
 677     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) drag_source
; 
 678     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 680     return wxtree_model
->internal
->row_draggable( drag_source
, path 
); 
 684 wxgtk_tree_model_drag_data_delete (GtkTreeDragSource 
*drag_source
, 
 687     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) drag_source
; 
 688     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 690     return wxtree_model
->internal
->drag_data_delete( drag_source
, path 
); 
 694 wxgtk_tree_model_drag_data_get (GtkTreeDragSource 
*drag_source
, 
 696                                 GtkSelectionData  
*selection_data
) 
 698     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) drag_source
; 
 699     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 702     wxPrintf( "drag_get_data\n"); 
 704     wxGtkString 
atom_selection(gdk_atom_name(selection_data
->selection
)); 
 705     wxPrintf( "selection %s\n", wxString::FromAscii(atom_selection
) ); 
 707     wxGtkString 
atom_target(gdk_atom_name(selection_data
->target
)); 
 708     wxPrintf( "target %s\n", wxString::FromAscii(atom_target
) ); 
 710     wxGtkString 
atom_type(gdk_atom_name(selection_data
->type
)); 
 711     wxPrintf( "type %s\n", wxString::FromAscii(atom_type
) ); 
 713     wxPrintf( "format %d\n", selection_data
->format 
); 
 716     return wxtree_model
->internal
->drag_data_get( drag_source
, path
, selection_data 
); 
 720 wxgtk_tree_model_drag_data_received (GtkTreeDragDest  
*drag_dest
, 
 722                                      GtkSelectionData 
*selection_data
) 
 724     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) drag_dest
; 
 725     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 727     return wxtree_model
->internal
->drag_data_received( drag_dest
, dest
, selection_data 
); 
 731 wxgtk_tree_model_row_drop_possible (GtkTreeDragDest  
*drag_dest
, 
 732                                     GtkTreePath      
*dest_path
, 
 733                                     GtkSelectionData 
*selection_data
) 
 735     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) drag_dest
; 
 736     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 738     return wxtree_model
->internal
->row_drop_possible( drag_dest
, dest_path
, selection_data 
); 
 743 wxgtk_tree_model_get_sort_column_id (GtkTreeSortable 
*sortable
, 
 744                                      gint            
*sort_column_id
, 
 747     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) sortable
; 
 749     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (sortable
), FALSE
); 
 751     if (!wxtree_model
->internal
->IsSorted()) 
 754             *sort_column_id 
= -1; 
 761         *sort_column_id 
= wxtree_model
->internal
->GetSortColumn(); 
 764         *order 
= wxtree_model
->internal
->GetSortOrder(); 
 769 wxDataViewColumn 
*gs_lastLeftClickHeader 
= NULL
; 
 772 wxgtk_tree_model_set_sort_column_id (GtkTreeSortable 
*sortable
, 
 776     GtkWxTreeModel 
*tree_model 
= (GtkWxTreeModel 
*) sortable
; 
 777     g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable
) ); 
 779     tree_model
->internal
->SetDataViewSortColumn( gs_lastLeftClickHeader 
); 
 781     if ((sort_column_id 
!= (gint
) tree_model
->internal
->GetSortColumn()) || 
 782         (order 
!= tree_model
->internal
->GetSortOrder())) 
 784         tree_model
->internal
->SetSortColumn( sort_column_id 
); 
 785         tree_model
->internal
->SetSortOrder( order 
); 
 787         gtk_tree_sortable_sort_column_changed (sortable
); 
 789         tree_model
->internal
->GetDataViewModel()->Resort(); 
 792     if (gs_lastLeftClickHeader
) 
 794         wxDataViewCtrl 
*dv 
= tree_model
->internal
->GetOwner(); 
 795         wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED
, dv
->GetId() ); 
 796         event
.SetDataViewColumn( gs_lastLeftClickHeader 
); 
 797         event
.SetModel( dv
->GetModel() ); 
 798         dv
->HandleWindowEvent( event 
); 
 801     gs_lastLeftClickHeader 
= NULL
; 
 805 wxgtk_tree_model_set_sort_func (GtkTreeSortable        
*sortable
, 
 806                                 gint                    
WXUNUSED(sort_column_id
), 
 807                                 GtkTreeIterCompareFunc  func
, 
 808                                 gpointer                
WXUNUSED(data
), 
 809                                 GtkDestroyNotify        
WXUNUSED(destroy
) ) 
 811     g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable
) ); 
 812     g_return_if_fail (func 
!= NULL
); 
 815 void     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" ); 
 826 gboolean 
wxgtk_tree_model_has_default_sort_func (GtkTreeSortable        
*sortable
) 
 828     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (sortable
), FALSE 
); 
 833 //----------------------------------------------------------------------------- 
 834 // define new GTK+ class wxGtkRendererRenderer 
 835 //----------------------------------------------------------------------------- 
 839 #define GTK_TYPE_WX_CELL_RENDERER               (gtk_wx_cell_renderer_get_type ()) 
 840 #define GTK_WX_CELL_RENDERER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRenderer)) 
 841 #define GTK_WX_CELL_RENDERER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRendererClass)) 
 842 #define GTK_IS_WX_CELL_RENDERER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_CELL_RENDERER)) 
 843 #define GTK_IS_WX_CELL_RENDERER_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_CELL_RENDERER)) 
 844 #define GTK_WX_CELL_RENDERER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRendererClass)) 
 846 GType            
gtk_wx_cell_renderer_get_type (void); 
 848 typedef struct _GtkWxCellRenderer GtkWxCellRenderer
; 
 849 typedef struct _GtkWxCellRendererClass GtkWxCellRendererClass
; 
 851 struct _GtkWxCellRenderer
 
 853   GtkCellRenderer parent
; 
 856   wxDataViewCustomRenderer 
*cell
; 
 860 struct _GtkWxCellRendererClass
 
 862   GtkCellRendererClass cell_parent_class
; 
 866 static GtkCellRenderer 
*gtk_wx_cell_renderer_new   (void); 
 867 static void gtk_wx_cell_renderer_init ( 
 868                         GtkWxCellRenderer      
*cell 
); 
 869 static void gtk_wx_cell_renderer_class_init( 
 870                         GtkWxCellRendererClass 
*klass 
); 
 871 static void gtk_wx_cell_renderer_finalize ( 
 873 static void gtk_wx_cell_renderer_get_size ( 
 874                         GtkCellRenderer         
*cell
, 
 876                         GdkRectangle            
*rectangle
, 
 881 static void gtk_wx_cell_renderer_render ( 
 882                         GtkCellRenderer         
*cell
, 
 885                         GdkRectangle            
*background_area
, 
 886                         GdkRectangle            
*cell_area
, 
 887                         GdkRectangle            
*expose_area
, 
 888                         GtkCellRendererState     flags 
); 
 889 static gboolean 
gtk_wx_cell_renderer_activate( 
 890                         GtkCellRenderer         
*cell
, 
 894                         GdkRectangle            
*background_area
, 
 895                         GdkRectangle            
*cell_area
, 
 896                         GtkCellRendererState     flags 
); 
 897 static GtkCellEditable 
*gtk_wx_cell_renderer_start_editing( 
 898                         GtkCellRenderer         
*cell
, 
 902                         GdkRectangle            
*background_area
, 
 903                         GdkRectangle            
*cell_area
, 
 904                         GtkCellRendererState     flags 
); 
 907 static GObjectClass 
*cell_parent_class 
= NULL
; 
 912 gtk_wx_cell_renderer_get_type (void) 
 914     static GType cell_wx_type 
= 0; 
 918         const GTypeInfo cell_wx_info 
= 
 920             sizeof (GtkWxCellRendererClass
), 
 921             NULL
, /* base_init */ 
 922             NULL
, /* base_finalize */ 
 923             (GClassInitFunc
) gtk_wx_cell_renderer_class_init
, 
 924             NULL
, /* class_finalize */ 
 925             NULL
, /* class_data */ 
 926             sizeof (GtkWxCellRenderer
), 
 928             (GInstanceInitFunc
) gtk_wx_cell_renderer_init
, 
 931         cell_wx_type 
= g_type_register_static( GTK_TYPE_CELL_RENDERER
, 
 932             "GtkWxCellRenderer", &cell_wx_info
, (GTypeFlags
)0 ); 
 939 gtk_wx_cell_renderer_init (GtkWxCellRenderer 
*cell
) 
 942     cell
->last_click 
= 0; 
 946 gtk_wx_cell_renderer_class_init (GtkWxCellRendererClass 
*klass
) 
 948     GObjectClass 
*object_class 
= G_OBJECT_CLASS (klass
); 
 949     GtkCellRendererClass 
*cell_class 
= GTK_CELL_RENDERER_CLASS (klass
); 
 951     cell_parent_class 
= (GObjectClass
*) g_type_class_peek_parent (klass
); 
 953     object_class
->finalize 
= gtk_wx_cell_renderer_finalize
; 
 955     cell_class
->get_size 
= gtk_wx_cell_renderer_get_size
; 
 956     cell_class
->render 
= gtk_wx_cell_renderer_render
; 
 957     cell_class
->activate 
= gtk_wx_cell_renderer_activate
; 
 958     cell_class
->start_editing 
= gtk_wx_cell_renderer_start_editing
; 
 962 gtk_wx_cell_renderer_finalize (GObject 
*object
) 
 965     (* G_OBJECT_CLASS (cell_parent_class
)->finalize
) (object
); 
 969 gtk_wx_cell_renderer_new (void) 
 971     return (GtkCellRenderer
*) g_object_new (GTK_TYPE_WX_CELL_RENDERER
, NULL
); 
 976 static GtkCellEditable 
*gtk_wx_cell_renderer_start_editing( 
 977                         GtkCellRenderer         
*renderer
, 
 978                         GdkEvent                
*WXUNUSED(event
), 
 981                         GdkRectangle            
*WXUNUSED(background_area
), 
 982                         GdkRectangle            
*cell_area
, 
 983                         GtkCellRendererState     
WXUNUSED(flags
) ) 
 985     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
 986     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
 988     // Renderer doesn't support in-place editing 
 989     if (!cell
->HasEditorCtrl()) 
 992     // An in-place editing control is still around 
 993     if (cell
->GetEditorCtrl()) 
 997     gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
, 
1003     rect
.x 
+= cell_area
->x
; 
1004     rect
.y 
+= cell_area
->y
; 
1005 //    rect.width  -= renderer->xpad * 2; 
1006 //    rect.height -= renderer->ypad * 2; 
1008 //    wxRect renderrect( rect.x, rect.y, rect.width, rect.height ); 
1009     wxRect 
renderrect( cell_area
->x
, cell_area
->y
, cell_area
->width
, cell_area
->height 
); 
1011     GtkTreePath 
*treepath 
= gtk_tree_path_new_from_string( path 
); 
1013     cell
->GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter
, treepath 
); 
1014     wxDataViewItem 
item( (void*) iter
.user_data 
); 
1015     gtk_tree_path_free( treepath 
); 
1017     cell
->StartEditing( item
, renderrect 
); 
1023 gtk_wx_cell_renderer_get_size (GtkCellRenderer 
*renderer
, 
1024                                GtkWidget       
*WXUNUSED(widget
), 
1025                                GdkRectangle    
*cell_area
, 
1031     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
1032     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
1034     wxSize size 
= cell
->GetSize(); 
1036     gint calc_width  
= (gint
) renderer
->xpad 
* 2 + size
.x
; 
1037     gint calc_height 
= (gint
) renderer
->ypad 
* 2 + size
.y
; 
1044     if (cell_area 
&& size
.x 
> 0 && size
.y 
> 0) 
1048             *x_offset 
= (gint
)((renderer
->xalign 
* 
1049                                (cell_area
->width 
- calc_width 
- 2 * renderer
->xpad
))); 
1050             *x_offset 
= MAX (*x_offset
, 0) + renderer
->xpad
; 
1054             *y_offset 
= (gint
)((renderer
->yalign 
* 
1055                                (cell_area
->height 
- calc_height 
- 2 * renderer
->ypad
))); 
1056             *y_offset 
= MAX (*y_offset
, 0) + renderer
->ypad
; 
1061         *width 
= calc_width
; 
1064         *height 
= calc_height
; 
1068 gtk_wx_cell_renderer_render (GtkCellRenderer      
*renderer
, 
1071                              GdkRectangle         
*background_area
, 
1072                              GdkRectangle         
*cell_area
, 
1073                              GdkRectangle         
*expose_area
, 
1074                              GtkCellRendererState  flags
) 
1077     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
1078     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
1080     cell
->window 
= window
; 
1081     cell
->widget 
= widget
; 
1082     cell
->background_area 
= (void*) background_area
; 
1083     cell
->cell_area 
= (void*) cell_area
; 
1084     cell
->expose_area 
= (void*) expose_area
; 
1085     cell
->flags 
= (int) flags
; 
1088     gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
, 
1094     rect
.x 
+= cell_area
->x
; 
1095     rect
.y 
+= cell_area
->y
; 
1096     rect
.width  
-= renderer
->xpad 
* 2; 
1097     rect
.height 
-= renderer
->ypad 
* 2; 
1100     if (gdk_rectangle_intersect (expose_area
, &rect
, &dummy
)) 
1102         wxRect 
renderrect( rect
.x
, rect
.y
, rect
.width
, rect
.height 
); 
1103         wxWindowDC
* dc 
= (wxWindowDC
*) cell
->GetDC(); 
1104         wxWindowDCImpl 
*impl 
= (wxWindowDCImpl 
*) dc
->GetImpl(); 
1105         if (impl
->m_gdkwindow 
== NULL
) 
1107             impl
->m_gdkwindow 
= window
; 
1112         if (flags 
& GTK_CELL_RENDERER_SELECTED
) 
1113             state 
|= wxDATAVIEW_CELL_SELECTED
; 
1114         if (flags 
& GTK_CELL_RENDERER_PRELIT
) 
1115             state 
|= wxDATAVIEW_CELL_PRELIT
; 
1116         if (flags 
& GTK_CELL_RENDERER_INSENSITIVE
) 
1117             state 
|= wxDATAVIEW_CELL_INSENSITIVE
; 
1118         if (flags 
& GTK_CELL_RENDERER_INSENSITIVE
) 
1119             state 
|= wxDATAVIEW_CELL_INSENSITIVE
; 
1120         if (flags 
& GTK_CELL_RENDERER_FOCUSED
) 
1121             state 
|= wxDATAVIEW_CELL_FOCUSED
; 
1122         cell
->Render( renderrect
, dc
, state 
); 
1127 gtk_wx_cell_renderer_activate( 
1128                         GtkCellRenderer         
*renderer
, 
1132                         GdkRectangle            
*WXUNUSED(background_area
), 
1133                         GdkRectangle            
*cell_area
, 
1134                         GtkCellRendererState     
WXUNUSED(flags
) ) 
1136     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
1137     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
1140     gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
, 
1146     rect
.x 
+= cell_area
->x
; 
1147     rect
.y 
+= cell_area
->y
; 
1148     rect
.width  
-= renderer
->xpad 
* 2; 
1149     rect
.height 
-= renderer
->ypad 
* 2; 
1151     wxRect 
renderrect( rect
.x
, rect
.y
, rect
.width
, rect
.height 
); 
1153     wxDataViewModel 
*model 
= cell
->GetOwner()->GetOwner()->GetModel(); 
1155     GtkTreePath 
*treepath 
= gtk_tree_path_new_from_string( path 
); 
1158     cell
->GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter
, treepath 
); 
1159     wxDataViewItem 
item( iter
.user_data 
); 
1160     gtk_tree_path_free( treepath 
); 
1162     unsigned int model_col 
= cell
->GetOwner()->GetModelColumn(); 
1168         // activated by <ENTER> 
1169         if (cell
->Activate( renderrect
, model
, item
, model_col 
)) 
1174     else if (event
->type 
== GDK_BUTTON_PRESS
) 
1176         GdkEventButton 
*button_event 
= (GdkEventButton
*) event
; 
1177         wxPoint 
pt( ((int) button_event
->x
) - renderrect
.x
, 
1178                     ((int) button_event
->y
) - renderrect
.y 
); 
1181         if (button_event
->button 
== 1) 
1183             if (cell
->LeftClick( pt
, renderrect
, model
, item
, model_col 
)) 
1185             // TODO: query system double-click time 
1186             if (button_event
->time 
- wxrenderer
->last_click 
< 400) 
1187                 if (cell
->Activate( renderrect
, model
, item
, model_col 
)) 
1190         wxrenderer
->last_click 
= button_event
->time
; 
1198 // --------------------------------------------------------- 
1199 // wxGtkDataViewModelNotifier 
1200 // --------------------------------------------------------- 
1202 class wxGtkDataViewModelNotifier
: public wxDataViewModelNotifier
 
1205     wxGtkDataViewModelNotifier( GtkWxTreeModel  
*wxgtk_model
, 
1206                                 wxDataViewModel 
*wx_model
, 
1207                                 wxDataViewCtrl  
*ctrl 
); 
1208     ~wxGtkDataViewModelNotifier(); 
1210     virtual bool ItemAdded( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
); 
1211     virtual bool ItemDeleted( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
); 
1212     virtual bool ItemChanged( const wxDataViewItem 
&item 
); 
1213     virtual bool ValueChanged( const wxDataViewItem 
&item
, unsigned int col 
); 
1214     virtual bool Cleared(); 
1215     virtual void Resort(); 
1217     void SetGtkModel( GtkWxTreeModel 
*model 
) { m_wxgtk_model 
= model
; } 
1220     GtkWxTreeModel      
*m_wxgtk_model
; 
1221     wxDataViewModel     
*m_wx_model
; 
1222     wxDataViewCtrl      
*m_owner
; 
1225 // --------------------------------------------------------- 
1226 // wxGtkDataViewListModelNotifier 
1227 // --------------------------------------------------------- 
1229 wxGtkDataViewModelNotifier::wxGtkDataViewModelNotifier( 
1230     GtkWxTreeModel
* wxgtk_model
, wxDataViewModel 
*wx_model
, 
1231     wxDataViewCtrl 
*ctrl 
) 
1233     m_wxgtk_model 
= wxgtk_model
; 
1234     m_wx_model 
= wx_model
; 
1238 wxGtkDataViewModelNotifier::~wxGtkDataViewModelNotifier() 
1241     m_wxgtk_model 
= NULL
; 
1244 bool wxGtkDataViewModelNotifier::ItemAdded( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
) 
1246     m_owner
->GtkGetInternal()->ItemAdded( parent
, item 
); 
1249     iter
.stamp 
= m_wxgtk_model
->stamp
; 
1250     iter
.user_data 
= (gpointer
) item
.GetID(); 
1252     GtkTreePath 
*path 
= wxgtk_tree_model_get_path( 
1253         GTK_TREE_MODEL(m_wxgtk_model
), &iter 
); 
1254     gtk_tree_model_row_inserted( 
1255         GTK_TREE_MODEL(m_wxgtk_model
), path
, &iter
); 
1256     gtk_tree_path_free (path
); 
1261 bool wxGtkDataViewModelNotifier::ItemDeleted( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
) 
1264     iter
.stamp 
= m_wxgtk_model
->stamp
; 
1265     iter
.user_data 
= (gpointer
) item
.GetID(); 
1267     GtkTreePath 
*path 
= wxgtk_tree_model_get_path( 
1268         GTK_TREE_MODEL(m_wxgtk_model
), &iter 
); 
1269     gtk_tree_model_row_deleted( 
1270         GTK_TREE_MODEL(m_wxgtk_model
), path 
); 
1271     gtk_tree_path_free (path
); 
1273     m_owner
->GtkGetInternal()->ItemDeleted( parent
, item 
); 
1278 void wxGtkDataViewModelNotifier::Resort() 
1280     m_owner
->GtkGetInternal()->Resort(); 
1283 bool wxGtkDataViewModelNotifier::ItemChanged( const wxDataViewItem 
&item 
) 
1286     iter
.stamp 
= m_wxgtk_model
->stamp
; 
1287     iter
.user_data 
= (gpointer
) item
.GetID(); 
1289     GtkTreePath 
*path 
= wxgtk_tree_model_get_path( 
1290         GTK_TREE_MODEL(m_wxgtk_model
), &iter 
); 
1291     gtk_tree_model_row_changed( 
1292         GTK_TREE_MODEL(m_wxgtk_model
), path
, &iter 
); 
1293     gtk_tree_path_free (path
); 
1295     m_owner
->GtkGetInternal()->ItemChanged( item 
); 
1300 bool wxGtkDataViewModelNotifier::ValueChanged( const wxDataViewItem 
&item
, unsigned int model_col 
) 
1302     // This adds GTK+'s missing MVC logic for ValueChanged 
1304     for (index 
= 0; index 
< m_owner
->GetColumnCount(); index
++) 
1306         wxDataViewColumn 
*column 
= m_owner
->GetColumn( index 
); 
1307         if (column
->GetModelColumn() == model_col
) 
1309             GtkTreeView 
*widget 
= GTK_TREE_VIEW(m_owner
->m_treeview
); 
1310             GtkTreeViewColumn 
*gcolumn 
= GTK_TREE_VIEW_COLUMN(column
->GetGtkHandle()); 
1314             iter
.stamp 
= m_wxgtk_model
->stamp
; 
1315             iter
.user_data 
= (gpointer
) item
.GetID(); 
1316             GtkTreePath 
*path 
= wxgtk_tree_model_get_path( 
1317                 GTK_TREE_MODEL(m_wxgtk_model
), &iter 
); 
1318             GdkRectangle cell_area
; 
1319             gtk_tree_view_get_cell_area( widget
, path
, gcolumn
, &cell_area 
); 
1320             gtk_tree_path_free( path 
); 
1322             GtkAdjustment
* hadjust 
= gtk_tree_view_get_hadjustment( widget 
); 
1323             double d 
= gtk_adjustment_get_value( hadjust 
); 
1324             int xdiff 
= (int) d
; 
1326             int ydiff 
= gcolumn
->button
->allocation
.height
; 
1328             gtk_widget_queue_draw_area( GTK_WIDGET(widget
), 
1329                 cell_area
.x 
- xdiff
, ydiff 
+ cell_area
.y
, cell_area
.width
, cell_area
.height 
); 
1331             m_owner
->GtkGetInternal()->ValueChanged( item
, model_col 
); 
1340 bool wxGtkDataViewModelNotifier::Cleared() 
1342     gtk_tree_view_set_model( GTK_TREE_VIEW(m_owner
->m_treeview
), NULL 
); 
1344     // this will create a new GTK model 
1345     m_owner
->GtkGetInternal()->Cleared(); 
1347     SetGtkModel( m_owner
->GtkGetInternal()->GetGtkModel() ); 
1349     gtk_tree_view_set_model( GTK_TREE_VIEW(m_owner
->m_treeview
), GTK_TREE_MODEL(m_wxgtk_model
) ); 
1354 // --------------------------------------------------------- 
1355 // wxDataViewRenderer 
1356 // --------------------------------------------------------- 
1358 static gpointer s_user_data 
= NULL
; 
1361 wxgtk_cell_editable_editing_done( GtkCellEditable 
*WXUNUSED(editable
), 
1362                                   wxDataViewRenderer 
*wxrenderer 
) 
1364     wxDataViewColumn 
*column 
= wxrenderer
->GetOwner(); 
1365     wxDataViewCtrl 
*dv 
= column
->GetOwner(); 
1366     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_DONE
, dv
->GetId() ); 
1367     event
.SetDataViewColumn( column 
); 
1368     event
.SetModel( dv
->GetModel() ); 
1369     wxDataViewItem 
item( s_user_data 
); 
1370     event
.SetItem( item 
); 
1371     dv
->HandleWindowEvent( event 
); 
1375 wxgtk_renderer_editing_started( GtkCellRenderer 
*WXUNUSED(cell
), GtkCellEditable 
*editable
, 
1376                                 gchar 
*path
, wxDataViewRenderer 
*wxrenderer 
) 
1378     wxDataViewColumn 
*column 
= wxrenderer
->GetOwner(); 
1379     wxDataViewCtrl 
*dv 
= column
->GetOwner(); 
1380     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_STARTED
, dv
->GetId() ); 
1381     event
.SetDataViewColumn( column 
); 
1382     event
.SetModel( dv
->GetModel() ); 
1383     GtkTreePath 
*tree_path 
= gtk_tree_path_new_from_string( path 
); 
1385     dv
->GtkGetInternal()->get_iter( &iter
, tree_path 
); 
1386     gtk_tree_path_free( tree_path 
); 
1387     wxDataViewItem 
item( iter
.user_data 
); 
1388     event
.SetItem( item 
); 
1389     dv
->HandleWindowEvent( event 
); 
1391     if (GTK_IS_CELL_EDITABLE(editable
)) 
1393         s_user_data 
= iter
.user_data
; 
1395         g_signal_connect (GTK_CELL_EDITABLE (editable
), "editing_done", 
1396             G_CALLBACK (wxgtk_cell_editable_editing_done
), 
1397             (gpointer
) wxrenderer 
); 
1403 IMPLEMENT_ABSTRACT_CLASS(wxDataViewRenderer
, wxDataViewRendererBase
) 
1405 wxDataViewRenderer::wxDataViewRenderer( const wxString 
&varianttype
, wxDataViewCellMode mode
, 
1407     wxDataViewRendererBase( varianttype
, mode
, align 
) 
1411     // NOTE: SetMode() and SetAlignment() needs to be called in the renderer's ctor, 
1412     //       after the m_renderer pointer has been initialized 
1415 void wxDataViewRenderer::GtkInitHandlers() 
1417     if (!gtk_check_version(2,6,0)) 
1419         g_signal_connect (GTK_CELL_RENDERER(m_renderer
), "editing_started", 
1420                     G_CALLBACK (wxgtk_renderer_editing_started
), 
1425 void wxDataViewRenderer::SetMode( wxDataViewCellMode mode 
) 
1427     GtkCellRendererMode gtkMode
; 
1430         case wxDATAVIEW_CELL_INERT
: 
1431             gtkMode 
= GTK_CELL_RENDERER_MODE_INERT
; 
1434         case wxDATAVIEW_CELL_ACTIVATABLE
: 
1435             gtkMode 
= GTK_CELL_RENDERER_MODE_ACTIVATABLE
; 
1438         case wxDATAVIEW_CELL_EDITABLE
: 
1439             gtkMode 
= GTK_CELL_RENDERER_MODE_EDITABLE
; 
1443             wxFAIL_MSG( "unknown wxDataViewCellMode value" ); 
1447     // This value is most often ignored in GtkTreeView 
1448     GValue gvalue 
= { 0, }; 
1449     g_value_init( &gvalue
, gtk_cell_renderer_mode_get_type() ); 
1450     g_value_set_enum( &gvalue
, gtkMode 
); 
1451     g_object_set_property( G_OBJECT(m_renderer
), "mode", &gvalue 
); 
1452     g_value_unset( &gvalue 
); 
1455 wxDataViewCellMode 
wxDataViewRenderer::GetMode() const 
1457     wxDataViewCellMode ret
; 
1460     g_object_get( G_OBJECT(m_renderer
), "mode", &gvalue
, NULL
); 
1462     switch (g_value_get_enum(&gvalue
)) 
1465             wxFAIL_MSG( "unknown GtkCellRendererMode value" ); 
1466             // fall through (we have to return something) 
1468         case GTK_CELL_RENDERER_MODE_INERT
: 
1469             ret 
= wxDATAVIEW_CELL_INERT
; 
1472         case GTK_CELL_RENDERER_MODE_ACTIVATABLE
: 
1473             ret 
= wxDATAVIEW_CELL_ACTIVATABLE
; 
1476         case GTK_CELL_RENDERER_MODE_EDITABLE
: 
1477             ret 
= wxDATAVIEW_CELL_EDITABLE
; 
1481     g_value_unset( &gvalue 
); 
1486 void wxDataViewRenderer::GtkUpdateAlignment() 
1488     int align 
= m_alignment
; 
1490     // query alignment from column ? 
1494         if (GetOwner() == NULL
) 
1497         align 
= GetOwner()->GetAlignment(); 
1498         align 
|= wxALIGN_CENTRE_VERTICAL
; 
1501     // horizontal alignment: 
1503     gfloat xalign 
= 0.0; 
1504     if (align 
& wxALIGN_RIGHT
) 
1506     else if (align 
& wxALIGN_CENTER_HORIZONTAL
) 
1509     GValue gvalue 
= { 0, }; 
1510     g_value_init( &gvalue
, G_TYPE_FLOAT 
); 
1511     g_value_set_float( &gvalue
, xalign 
); 
1512     g_object_set_property( G_OBJECT(m_renderer
), "xalign", &gvalue 
); 
1513     g_value_unset( &gvalue 
); 
1515     // vertical alignment: 
1517     gfloat yalign 
= 0.0; 
1518     if (align 
& wxALIGN_BOTTOM
) 
1520     else if (align 
& wxALIGN_CENTER_VERTICAL
) 
1523     GValue gvalue2 
= { 0, }; 
1524     g_value_init( &gvalue2
, G_TYPE_FLOAT 
); 
1525     g_value_set_float( &gvalue2
, yalign 
); 
1526     g_object_set_property( G_OBJECT(m_renderer
), "yalign", &gvalue2 
); 
1527     g_value_unset( &gvalue2 
); 
1530 void wxDataViewRenderer::SetAlignment( int align 
) 
1532     m_alignment 
= align
; 
1533     GtkUpdateAlignment(); 
1536 int wxDataViewRenderer::GetAlignment() const 
1541 // --------------------------------------------------------- 
1542 // wxDataViewTextRenderer 
1543 // --------------------------------------------------------- 
1546 static void wxGtkTextRendererEditedCallback( GtkCellRendererText 
*renderer
, 
1547     gchar 
*arg1
, gchar 
*arg2
, gpointer user_data 
); 
1550 static void wxGtkTextRendererEditedCallback( GtkCellRendererText 
*WXUNUSED(renderer
), 
1551     gchar 
*arg1
, gchar 
*arg2
, gpointer user_data 
) 
1553     wxDataViewRenderer 
*cell 
= (wxDataViewRenderer
*) user_data
; 
1555     wxString tmp 
= wxGTK_CONV_BACK_FONT(arg2
, cell
->GetOwner()->GetOwner()->GetFont()); 
1556     wxVariant value 
= tmp
; 
1557     if (!cell
->Validate( value 
)) 
1560     wxDataViewModel 
*model 
= cell
->GetOwner()->GetOwner()->GetModel(); 
1562     GtkTreePath 
*path 
= gtk_tree_path_new_from_string( arg1 
); 
1564     cell
->GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter
, path 
); 
1565     wxDataViewItem 
item( (void*) iter
.user_data 
);; 
1566     gtk_tree_path_free( path 
); 
1568     unsigned int model_col 
= cell
->GetOwner()->GetModelColumn(); 
1570     model
->SetValue( value
, item
, model_col 
); 
1571     model
->ValueChanged( item
, model_col 
); 
1574 IMPLEMENT_CLASS(wxDataViewTextRenderer
, wxDataViewRenderer
) 
1576 wxDataViewTextRenderer::wxDataViewTextRenderer( const wxString 
&varianttype
, wxDataViewCellMode mode
, 
1578     wxDataViewRenderer( varianttype
, mode
, align 
) 
1580     m_renderer 
= (GtkCellRenderer
*) gtk_cell_renderer_text_new(); 
1582     if (mode 
& wxDATAVIEW_CELL_EDITABLE
) 
1584         GValue gvalue 
= { 0, }; 
1585         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1586         g_value_set_boolean( &gvalue
, true ); 
1587         g_object_set_property( G_OBJECT(m_renderer
), "editable", &gvalue 
); 
1588         g_value_unset( &gvalue 
); 
1590         g_signal_connect_after( m_renderer
, "edited", G_CALLBACK(wxGtkTextRendererEditedCallback
), this ); 
1596     SetAlignment(align
); 
1599 bool wxDataViewTextRenderer::SetValue( const wxVariant 
&value 
) 
1601     wxString tmp 
= value
; 
1603     GValue gvalue 
= { 0, }; 
1604     g_value_init( &gvalue
, G_TYPE_STRING 
); 
1605     g_value_set_string( &gvalue
, wxGTK_CONV_FONT( tmp
, GetOwner()->GetOwner()->GetFont() ) ); 
1606     g_object_set_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
1607     g_value_unset( &gvalue 
); 
1612 bool wxDataViewTextRenderer::GetValue( wxVariant 
&value 
) const 
1614     GValue gvalue 
= { 0, }; 
1615     g_value_init( &gvalue
, G_TYPE_STRING 
); 
1616     g_object_get_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
1617     wxString tmp 
= wxGTK_CONV_BACK_FONT( g_value_get_string( &gvalue 
), const_cast<wxDataViewTextRenderer
*>(this)->GetOwner()->GetOwner()->GetFont() ); 
1618     g_value_unset( &gvalue 
); 
1625 void wxDataViewTextRenderer::SetAlignment( int align 
) 
1627     wxDataViewRenderer::SetAlignment(align
); 
1629     if (gtk_check_version(2,10,0)) 
1632     // horizontal alignment: 
1633     PangoAlignment pangoAlign 
= PANGO_ALIGN_LEFT
; 
1634     if (align 
& wxALIGN_RIGHT
) 
1635         pangoAlign 
= PANGO_ALIGN_RIGHT
; 
1636     else if (align 
& wxALIGN_CENTER_HORIZONTAL
) 
1637         pangoAlign 
= PANGO_ALIGN_CENTER
; 
1639     GValue gvalue 
= { 0, }; 
1640     g_value_init( &gvalue
, gtk_cell_renderer_mode_get_type() ); 
1641     g_value_set_enum( &gvalue
, pangoAlign 
); 
1642     g_object_set_property( G_OBJECT(m_renderer
), "alignment", &gvalue 
); 
1643     g_value_unset( &gvalue 
); 
1646 // --------------------------------------------------------- 
1647 // wxDataViewTextRendererAttr 
1648 // --------------------------------------------------------- 
1650 IMPLEMENT_CLASS(wxDataViewTextRendererAttr
,wxDataViewTextRenderer
) 
1652 wxDataViewTextRendererAttr::wxDataViewTextRendererAttr( const wxString 
&varianttype
, 
1653                             wxDataViewCellMode mode
, int align 
) : 
1654    wxDataViewTextRenderer( varianttype
, mode
, align 
) 
1658 // --------------------------------------------------------- 
1659 // wxDataViewBitmapRenderer 
1660 // --------------------------------------------------------- 
1662 IMPLEMENT_CLASS(wxDataViewBitmapRenderer
, wxDataViewRenderer
) 
1664 wxDataViewBitmapRenderer::wxDataViewBitmapRenderer( const wxString 
&varianttype
, wxDataViewCellMode mode
, 
1666     wxDataViewRenderer( varianttype
, mode
, align 
) 
1668     m_renderer 
= (GtkCellRenderer
*) gtk_cell_renderer_pixbuf_new(); 
1671     SetAlignment(align
); 
1674 bool wxDataViewBitmapRenderer::SetValue( const wxVariant 
&value 
) 
1676     if (value
.GetType() == wxT("wxBitmap")) 
1681         // This may create a Pixbuf representation in the 
1682         // wxBitmap object (and it will stay there) 
1683         GdkPixbuf 
*pixbuf 
= bitmap
.GetPixbuf(); 
1685         GValue gvalue 
= { 0, }; 
1686         g_value_init( &gvalue
, G_TYPE_OBJECT 
); 
1687         g_value_set_object( &gvalue
, pixbuf 
); 
1688         g_object_set_property( G_OBJECT(m_renderer
), "pixbuf", &gvalue 
); 
1689         g_value_unset( &gvalue 
); 
1694     if (value
.GetType() == wxT("wxIcon")) 
1699         // This may create a Pixbuf representation in the 
1700         // wxBitmap object (and it will stay there) 
1701         GdkPixbuf 
*pixbuf 
= bitmap
.GetPixbuf(); 
1703         GValue gvalue 
= { 0, }; 
1704         g_value_init( &gvalue
, G_TYPE_OBJECT 
); 
1705         g_value_set_object( &gvalue
, pixbuf 
); 
1706         g_object_set_property( G_OBJECT(m_renderer
), "pixbuf", &gvalue 
); 
1707         g_value_unset( &gvalue 
); 
1715 bool wxDataViewBitmapRenderer::GetValue( wxVariant 
&WXUNUSED(value
) ) const 
1720 // --------------------------------------------------------- 
1721 // wxDataViewToggleRenderer 
1722 // --------------------------------------------------------- 
1725 static void wxGtkToggleRendererToggledCallback( GtkCellRendererToggle 
*renderer
, 
1726     gchar 
*path
, gpointer user_data 
); 
1729 static void wxGtkToggleRendererToggledCallback( GtkCellRendererToggle 
*renderer
, 
1730     gchar 
*path
, gpointer user_data 
) 
1732     wxDataViewToggleRenderer 
*cell 
= (wxDataViewToggleRenderer
*) user_data
; 
1735     GValue gvalue 
= { 0, }; 
1736     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1737     g_object_get_property( G_OBJECT(renderer
), "active", &gvalue 
); 
1738     bool tmp 
= g_value_get_boolean( &gvalue 
); 
1739     g_value_unset( &gvalue 
); 
1743     wxVariant value 
= tmp
; 
1744     if (!cell
->Validate( value 
)) 
1747     wxDataViewModel 
*model 
= cell
->GetOwner()->GetOwner()->GetModel(); 
1749     GtkTreePath 
*gtk_path 
= gtk_tree_path_new_from_string( path 
); 
1751     cell
->GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter
, gtk_path 
); 
1752     wxDataViewItem 
item( (void*) iter
.user_data 
);; 
1753     gtk_tree_path_free( gtk_path 
); 
1755     unsigned int model_col 
= cell
->GetOwner()->GetModelColumn(); 
1757     model
->SetValue( value
, item
, model_col 
); 
1758     model
->ValueChanged( item
, model_col 
); 
1761 IMPLEMENT_CLASS(wxDataViewToggleRenderer
, wxDataViewRenderer
) 
1763 wxDataViewToggleRenderer::wxDataViewToggleRenderer( const wxString 
&varianttype
, 
1764                                                     wxDataViewCellMode mode
, int align 
) : 
1765     wxDataViewRenderer( varianttype
, mode
, align 
) 
1767     m_renderer 
= (GtkCellRenderer
*) gtk_cell_renderer_toggle_new(); 
1769     if (mode 
& wxDATAVIEW_CELL_ACTIVATABLE
) 
1771         g_signal_connect_after( m_renderer
, "toggled", 
1772                                 G_CALLBACK(wxGtkToggleRendererToggledCallback
), this ); 
1776         GValue gvalue 
= { 0, }; 
1777         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1778         g_value_set_boolean( &gvalue
, false ); 
1779         g_object_set_property( G_OBJECT(m_renderer
), "activatable", &gvalue 
); 
1780         g_value_unset( &gvalue 
); 
1784     SetAlignment(align
); 
1787 bool wxDataViewToggleRenderer::SetValue( const wxVariant 
&value 
) 
1791     GValue gvalue 
= { 0, }; 
1792     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1793     g_value_set_boolean( &gvalue
, tmp 
); 
1794     g_object_set_property( G_OBJECT(m_renderer
), "active", &gvalue 
); 
1795     g_value_unset( &gvalue 
); 
1800 bool wxDataViewToggleRenderer::GetValue( wxVariant 
&value 
) const 
1802     GValue gvalue 
= { 0, }; 
1803     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1804     g_object_get_property( G_OBJECT(m_renderer
), "active", &gvalue 
); 
1805     bool tmp 
= g_value_get_boolean( &gvalue 
); 
1806     g_value_unset( &gvalue 
); 
1813 // --------------------------------------------------------- 
1814 // wxDataViewCustomRenderer 
1815 // --------------------------------------------------------- 
1817 class wxDataViewCtrlDCImpl
: public wxWindowDCImpl
 
1820    wxDataViewCtrlDCImpl( wxDC 
*owner
, wxDataViewCtrl 
*window 
) : 
1821        wxWindowDCImpl( owner 
) 
1823         GtkWidget 
*widget 
= window
->m_treeview
; 
1829         m_context 
= window
->GtkGetPangoDefaultContext(); 
1830         m_layout 
= pango_layout_new( m_context 
); 
1831         m_fontdesc 
= pango_font_description_copy( widget
->style
->font_desc 
); 
1833         m_cmap 
= gtk_widget_get_colormap( widget 
? widget 
: window
->m_widget 
); 
1835         // Set m_gdkwindow later 
1840 class wxDataViewCtrlDC
: public wxWindowDC
 
1843     wxDataViewCtrlDC( wxDataViewCtrl 
*window 
) : 
1844         wxWindowDC( new wxDataViewCtrlDCImpl( this, window 
) ) 
1849 // --------------------------------------------------------- 
1850 // wxDataViewCustomRenderer 
1851 // --------------------------------------------------------- 
1853 IMPLEMENT_CLASS(wxDataViewCustomRenderer
, wxDataViewRenderer
) 
1855 wxDataViewCustomRenderer::wxDataViewCustomRenderer( const wxString 
&varianttype
, 
1856                                                     wxDataViewCellMode mode
, int align
, 
1858     wxDataViewRenderer( varianttype
, mode
, align 
) 
1861     m_text_renderer 
= NULL
; 
1869 void wxDataViewCustomRenderer::RenderText( const wxString 
&text
, int xoffset
, 
1870                                            wxRect 
WXUNUSED(cell
), wxDC 
*WXUNUSED(dc
), int WXUNUSED(state
) ) 
1873     wxDataViewCtrl 
*view 
= GetOwner()->GetOwner(); 
1874     wxColour col 
= (state 
& wxDATAVIEW_CELL_SELECTED
) ? 
1875                         wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT
) : 
1876                         view
->GetForegroundColour(); 
1877     dc
->SetTextForeground(col
); 
1878     dc
->DrawText( text
, cell
.x 
+ xoffset
, cell
.y 
+ ((cell
.height 
- dc
->GetCharHeight()) / 2)); 
1880     if (!m_text_renderer
) 
1881         m_text_renderer 
= gtk_cell_renderer_text_new(); 
1883     GValue gvalue 
= { 0, }; 
1884     g_value_init( &gvalue
, G_TYPE_STRING 
); 
1885     g_value_set_string( &gvalue
, wxGTK_CONV_FONT( text
, GetOwner()->GetOwner()->GetFont() ) ); 
1886     g_object_set_property( G_OBJECT(m_text_renderer
), "text", &gvalue 
); 
1887     g_value_unset( &gvalue 
); 
1889     ((GdkRectangle
*) cell_area
)->x 
+= xoffset
; 
1890     ((GdkRectangle
*) cell_area
)->width 
-= xoffset
; 
1892     gtk_cell_renderer_render( m_text_renderer
, 
1895         (GdkRectangle
*) background_area
, 
1896         (GdkRectangle
*) cell_area
, 
1897         (GdkRectangle
*) expose_area
, 
1898         (GtkCellRendererState
) flags 
); 
1900     ((GdkRectangle
*) cell_area
)->x 
-= xoffset
; 
1901     ((GdkRectangle
*) cell_area
)->width 
+= xoffset
; 
1905 bool wxDataViewCustomRenderer::Init(wxDataViewCellMode mode
, int align
) 
1907     GtkWxCellRenderer 
*renderer 
= (GtkWxCellRenderer 
*) gtk_wx_cell_renderer_new(); 
1908     renderer
->cell 
= this; 
1910     m_renderer 
= (GtkCellRenderer
*) renderer
; 
1913     SetAlignment(align
); 
1920 wxDataViewCustomRenderer::~wxDataViewCustomRenderer() 
1925     if (m_text_renderer
) 
1926         gtk_object_sink( GTK_OBJECT(m_text_renderer
) ); 
1929 wxDC 
*wxDataViewCustomRenderer::GetDC() 
1933         if (GetOwner() == NULL
) 
1935         if (GetOwner()->GetOwner() == NULL
) 
1937         m_dc 
= new wxDataViewCtrlDC( GetOwner()->GetOwner() ); 
1943 // --------------------------------------------------------- 
1944 // wxDataViewProgressRenderer 
1945 // --------------------------------------------------------- 
1947 IMPLEMENT_CLASS(wxDataViewProgressRenderer
, wxDataViewCustomRenderer
) 
1949 wxDataViewProgressRenderer::wxDataViewProgressRenderer( const wxString 
&label
, 
1950     const wxString 
&varianttype
, wxDataViewCellMode mode
, int align 
) : 
1951     wxDataViewCustomRenderer( varianttype
, mode
, align
, true ) 
1957     if (!gtk_check_version(2,6,0)) 
1959         m_renderer 
= (GtkCellRenderer
*) gtk_cell_renderer_progress_new(); 
1961         GValue gvalue 
= { 0, }; 
1962         g_value_init( &gvalue
, G_TYPE_STRING 
); 
1964         g_value_set_string( &gvalue
, wxGTK_CONV_FONT( m_label
, GetOwner()->GetOwner()->GetFont() ) ); 
1965         g_object_set_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
1966         g_value_unset( &gvalue 
); 
1969         SetAlignment(align
); 
1974         // Use custom cell code 
1975         wxDataViewCustomRenderer::Init(mode
, align
); 
1979 wxDataViewProgressRenderer::~wxDataViewProgressRenderer() 
1983 bool wxDataViewProgressRenderer::SetValue( const wxVariant 
&value 
) 
1986     if (!gtk_check_version(2,6,0)) 
1988         gint tmp 
= (long) value
; 
1989         GValue gvalue 
= { 0, }; 
1990         g_value_init( &gvalue
, G_TYPE_INT 
); 
1991         g_value_set_int( &gvalue
, tmp 
); 
1992         g_object_set_property( G_OBJECT(m_renderer
), "value", &gvalue 
); 
1993         g_value_unset( &gvalue 
); 
1998         m_value 
= (long) value
; 
2000         if (m_value 
< 0) m_value 
= 0; 
2001         if (m_value 
> 100) m_value 
= 100; 
2007 bool wxDataViewProgressRenderer::GetValue( wxVariant 
&WXUNUSED(value
) ) const 
2012 bool wxDataViewProgressRenderer::Render( wxRect cell
, wxDC 
*dc
, int WXUNUSED(state
) ) 
2014     double pct 
= (double)m_value 
/ 100.0; 
2016     bar
.width 
= (int)(cell
.width 
* pct
); 
2017     dc
->SetPen( *wxTRANSPARENT_PEN 
); 
2018     dc
->SetBrush( *wxBLUE_BRUSH 
); 
2019     dc
->DrawRectangle( bar 
); 
2021     dc
->SetBrush( *wxTRANSPARENT_BRUSH 
); 
2022     dc
->SetPen( *wxBLACK_PEN 
); 
2023     dc
->DrawRectangle( cell 
); 
2028 wxSize 
wxDataViewProgressRenderer::GetSize() const 
2030     return wxSize(40,12); 
2033 // ------------------------------------- 
2034 // wxDataViewChoiceRenderer 
2035 // ------------------------------------- 
2037 wxDataViewChoiceRenderer::wxDataViewChoiceRenderer( const wxArrayString 
&choices
, 
2038                             wxDataViewCellMode mode
, int alignment  
) : 
2039     wxDataViewCustomRenderer( "string", mode
, alignment
, true ) 
2041    m_choices 
= choices
; 
2044     if (!gtk_check_version(2,6,0)) 
2046         m_renderer 
= (GtkCellRenderer
*) gtk_cell_renderer_combo_new(); 
2048         GtkListStore 
*store 
= gtk_list_store_new( 1, G_TYPE_STRING 
); 
2050         for (n 
= 0; n 
< m_choices
.GetCount(); n
++) 
2051             gtk_list_store_insert_with_values( store
, NULL
, n
, 0, m_choices
[n
].utf8_str(), -1 ); 
2053         g_object_set (m_renderer
, 
2059         bool editable 
= (mode 
& wxDATAVIEW_CELL_EDITABLE
); 
2060         g_object_set (m_renderer
, "editable", editable
, NULL
); 
2062         SetAlignment(alignment
); 
2064         g_signal_connect_after( m_renderer
, "edited", G_CALLBACK(wxGtkTextRendererEditedCallback
), this ); 
2071         // Use custom cell code 
2072         wxDataViewCustomRenderer::Init(mode
, alignment
); 
2076 bool wxDataViewChoiceRenderer::Render( wxRect rect
, wxDC 
*dc
, int state 
) 
2078     RenderText( m_data
, 0, rect
, dc
, state 
); 
2082 wxSize 
wxDataViewChoiceRenderer::GetSize() const 
2084     return wxSize(70,20); 
2087 bool wxDataViewChoiceRenderer::SetValue( const wxVariant 
&value 
) 
2091     if (!gtk_check_version(2,6,0)) 
2093         GValue gvalue 
= { 0, }; 
2094         g_value_init( &gvalue
, G_TYPE_STRING 
); 
2095         g_value_set_string( &gvalue
, wxGTK_CONV_FONT( value
.GetString(), GetOwner()->GetOwner()->GetFont() ) ); 
2096         g_object_set_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
2097         g_value_unset( &gvalue 
); 
2101         m_data 
= value
.GetString(); 
2106 bool wxDataViewChoiceRenderer::GetValue( wxVariant 
&value 
) const 
2109     if (!gtk_check_version(2,6,0)) 
2111         GValue gvalue 
= { 0, }; 
2112         g_value_init( &gvalue
, G_TYPE_STRING 
); 
2113         g_object_get_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
2114         wxString temp 
= wxGTK_CONV_BACK_FONT( g_value_get_string( &gvalue 
), const_cast<wxDataViewTextRenderer
*>(this)->GetOwner()->GetOwner()->GetFont() ); 
2115         g_value_unset( &gvalue 
); 
2117         wxPrintf( "temp %s\n", temp 
); 
2126 void wxDataViewChoiceRenderer::SetAlignment( int align 
) 
2128     wxDataViewCustomRenderer::SetAlignment(align
); 
2130     if (gtk_check_version(2,10,0)) 
2133     // horizontal alignment: 
2134     PangoAlignment pangoAlign 
= PANGO_ALIGN_LEFT
; 
2135     if (align 
& wxALIGN_RIGHT
) 
2136         pangoAlign 
= PANGO_ALIGN_RIGHT
; 
2137     else if (align 
& wxALIGN_CENTER_HORIZONTAL
) 
2138         pangoAlign 
= PANGO_ALIGN_CENTER
; 
2140     GValue gvalue 
= { 0, }; 
2141     g_value_init( &gvalue
, gtk_cell_renderer_mode_get_type() ); 
2142     g_value_set_enum( &gvalue
, pangoAlign 
); 
2143     g_object_set_property( G_OBJECT(m_renderer
), "alignment", &gvalue 
); 
2144     g_value_unset( &gvalue 
); 
2147 // --------------------------------------------------------- 
2148 // wxDataViewDateRenderer 
2149 // --------------------------------------------------------- 
2151 class wxDataViewDateRendererPopupTransient
: public wxPopupTransientWindow
 
2154     wxDataViewDateRendererPopupTransient( wxWindow
* parent
, wxDateTime 
*value
, 
2155         wxDataViewModel 
*model
, const wxDataViewItem 
&item
, unsigned int col 
) : 
2156         wxPopupTransientWindow( parent
, wxBORDER_SIMPLE 
) 
2161         m_cal 
= new wxCalendarCtrl( this, -1, *value 
); 
2162         wxBoxSizer 
*sizer 
= new wxBoxSizer( wxHORIZONTAL 
); 
2163         sizer
->Add( m_cal
, 1, wxGROW 
); 
2168     virtual void OnDismiss() 
2172     void OnCalendar( wxCalendarEvent 
&event 
); 
2174     wxCalendarCtrl   
*m_cal
; 
2175     wxDataViewModel  
*m_model
; 
2176     wxDataViewItem    m_item
; 
2180     DECLARE_EVENT_TABLE() 
2183 BEGIN_EVENT_TABLE(wxDataViewDateRendererPopupTransient
,wxPopupTransientWindow
) 
2184     EVT_CALENDAR( -1, wxDataViewDateRendererPopupTransient::OnCalendar 
) 
2187 void wxDataViewDateRendererPopupTransient::OnCalendar( wxCalendarEvent 
&event 
) 
2189     wxDateTime date 
= event
.GetDate(); 
2190     wxVariant value 
= date
; 
2191     m_model
->SetValue( value
, m_item
, m_col 
); 
2192     m_model
->ValueChanged( m_item
, m_col 
); 
2196 IMPLEMENT_CLASS(wxDataViewDateRenderer
, wxDataViewCustomRenderer
) 
2198 wxDataViewDateRenderer::wxDataViewDateRenderer( const wxString 
&varianttype
, 
2199                         wxDataViewCellMode mode
, int align 
) : 
2200     wxDataViewCustomRenderer( varianttype
, mode
, align 
) 
2203     SetAlignment(align
); 
2206 bool wxDataViewDateRenderer::SetValue( const wxVariant 
&value 
) 
2208     m_date 
= value
.GetDateTime(); 
2213 bool wxDataViewDateRenderer::GetValue( wxVariant 
&WXUNUSED(value
) ) const 
2218 bool wxDataViewDateRenderer::Render( wxRect cell
, wxDC 
*dc
, int state 
) 
2220     dc
->SetFont( GetOwner()->GetOwner()->GetFont() ); 
2221     wxString tmp 
= m_date
.FormatDate(); 
2222     RenderText( tmp
, 0, cell
, dc
, state 
); 
2226 wxSize 
wxDataViewDateRenderer::GetSize() const 
2228     wxString tmp 
= m_date
.FormatDate(); 
2230     GetView()->GetTextExtent( tmp
, &x
, &y
, &d 
); 
2231     return wxSize(x
,y
+d
); 
2234 bool wxDataViewDateRenderer::Activate( wxRect 
WXUNUSED(cell
), wxDataViewModel 
*model
, 
2235                                        const wxDataViewItem 
&item
, unsigned int col 
) 
2238     model
->GetValue( variant
, item
, col 
); 
2239     wxDateTime value 
= variant
.GetDateTime(); 
2241     wxDataViewDateRendererPopupTransient 
*popup 
= new wxDataViewDateRendererPopupTransient( 
2242         GetOwner()->GetOwner()->GetParent(), &value
, model
, item
, col 
); 
2243     wxPoint pos 
= wxGetMousePosition(); 
2246     popup
->Popup( popup
->m_cal 
); 
2252 // --------------------------------------------------------- 
2253 // wxDataViewIconTextRenderer 
2254 // --------------------------------------------------------- 
2256 IMPLEMENT_CLASS(wxDataViewIconTextRenderer
, wxDataViewCustomRenderer
) 
2258 wxDataViewIconTextRenderer::wxDataViewIconTextRenderer( 
2259   const wxString 
&varianttype
, wxDataViewCellMode mode
, int align 
) : 
2260     wxDataViewCustomRenderer( varianttype
, mode
, align 
) 
2263     SetAlignment(align
); 
2266 wxDataViewIconTextRenderer::~wxDataViewIconTextRenderer() 
2270 bool wxDataViewIconTextRenderer::SetValue( const wxVariant 
&value 
) 
2276 bool wxDataViewIconTextRenderer::GetValue( wxVariant 
&WXUNUSED(value
) ) const 
2281 bool wxDataViewIconTextRenderer::Render( wxRect cell
, wxDC 
*dc
, int state 
) 
2283     const wxIcon 
&icon 
= m_value
.GetIcon(); 
2287         int yoffset 
= wxMax( 0, (cell
.height 
- icon
.GetHeight()) / 2 ); 
2288         dc
->DrawIcon( icon
, cell
.x
, cell
.y 
+ yoffset 
); 
2289         offset 
= icon
.GetWidth() + 4; 
2292     RenderText( m_value
.GetText(), offset
, cell
, dc
, state 
); 
2297 wxSize 
wxDataViewIconTextRenderer::GetSize() const 
2300     if (m_value
.GetIcon().IsOk()) 
2301         size
.x 
= 4 + m_value
.GetIcon().GetWidth(); 
2303     GetView()->GetTextExtent( m_value
.GetText(), &x
, &y
, &d 
); 
2309 wxControl
* wxDataViewIconTextRenderer::CreateEditorCtrl( 
2310     wxWindow 
*WXUNUSED(parent
), wxRect 
WXUNUSED(labelRect
), const wxVariant 
&WXUNUSED(value
) ) 
2315 bool wxDataViewIconTextRenderer::GetValueFromEditorCtrl( 
2316    wxControl
* WXUNUSED(editor
), wxVariant 
&WXUNUSED(value
) ) 
2321 // --------------------------------------------------------- 
2323 // --------------------------------------------------------- 
2327 gtk_dataview_header_button_press_callback( GtkWidget 
*WXUNUSED(widget
), 
2328                                            GdkEventButton 
*gdk_event
, 
2329                                            wxDataViewColumn 
*column 
) 
2331     if (gdk_event
->type 
!= GDK_BUTTON_PRESS
) 
2334     if (gdk_event
->button 
== 1) 
2336         gs_lastLeftClickHeader 
= column
; 
2338         wxDataViewCtrl 
*dv 
= column
->GetOwner(); 
2339         wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK
, dv
->GetId() ); 
2340         event
.SetDataViewColumn( column 
); 
2341         event
.SetModel( dv
->GetModel() ); 
2342         if (dv
->HandleWindowEvent( event 
)) 
2346     if (gdk_event
->button 
== 3) 
2348         wxDataViewCtrl 
*dv 
= column
->GetOwner(); 
2349         wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK
, dv
->GetId() ); 
2350         event
.SetDataViewColumn( column 
); 
2351         event
.SetModel( dv
->GetModel() ); 
2352         if (dv
->HandleWindowEvent( event 
)) 
2360 static void wxGtkTreeCellDataFunc( GtkTreeViewColumn 
*column
, 
2361                             GtkCellRenderer 
*cell
, 
2362                             GtkTreeModel 
*model
, 
2368 static void wxGtkTreeCellDataFunc( GtkTreeViewColumn 
*WXUNUSED(column
), 
2369                             GtkCellRenderer 
*renderer
, 
2370                             GtkTreeModel 
*model
, 
2374     g_return_if_fail (GTK_IS_WX_TREE_MODEL (model
)); 
2375     GtkWxTreeModel 
*tree_model 
= (GtkWxTreeModel 
*) model
; 
2377     wxDataViewRenderer 
*cell 
= (wxDataViewRenderer
*) data
; 
2379     wxDataViewItem 
item( (void*) iter
->user_data 
); 
2381     wxDataViewModel 
*wx_model 
= tree_model
->internal
->GetDataViewModel(); 
2383     if (!wx_model
->IsVirtualListModel()) 
2386     if (wx_model
->IsContainer( item 
)) 
2388         if (wx_model
->HasContainerColumns( item 
) || (cell
->GetOwner()->GetModelColumn() == 0)) 
2390             GValue gvalue 
= { 0, }; 
2391             g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
2392             g_value_set_boolean( &gvalue
, TRUE 
); 
2393             g_object_set_property( G_OBJECT(renderer
), "visible", &gvalue 
); 
2394             g_value_unset( &gvalue 
); 
2398             GValue gvalue 
= { 0, }; 
2399             g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
2400             g_value_set_boolean( &gvalue
, FALSE 
); 
2401             g_object_set_property( G_OBJECT(renderer
), "visible", &gvalue 
); 
2402             g_value_unset( &gvalue 
); 
2409         GValue gvalue 
= { 0, }; 
2410         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
2411         g_value_set_boolean( &gvalue
, TRUE 
); 
2412         g_object_set_property( G_OBJECT(renderer
), "visible", &gvalue 
); 
2413         g_value_unset( &gvalue 
); 
2419     wx_model
->GetValue( value
, item
, cell
->GetOwner()->GetModelColumn() ); 
2421     if (value
.GetType() != cell
->GetVariantType()) 
2422         wxLogError( wxT("Wrong type, required: %s but: %s"), 
2423                     value
.GetType().c_str(), 
2424                     cell
->GetVariantType().c_str() ); 
2426     cell
->SetValue( value 
); 
2428     if (cell
->GtkHasAttributes()) 
2430         wxDataViewItemAttr attr
; 
2431         bool colour_set 
= false; 
2432         bool style_set 
= false; 
2433         bool weight_set 
= false; 
2435         if (wx_model
->GetAttr( item
, cell
->GetOwner()->GetModelColumn(), attr 
)) 
2437             // this must be a GtkCellRendererText 
2438             wxColour colour 
= attr
.GetColour(); 
2441                 const GdkColor 
* const gcol 
= colour
.GetColor(); 
2443                 GValue gvalue 
= { 0, }; 
2444                 g_value_init( &gvalue
, GDK_TYPE_COLOR 
); 
2445                 g_value_set_boxed( &gvalue
, gcol 
); 
2446                 g_object_set_property( G_OBJECT(renderer
), "foreground_gdk", &gvalue 
); 
2447                 g_value_unset( &gvalue 
); 
2452             if (attr
.GetItalic()) 
2454                 GValue gvalue 
= { 0, }; 
2455                 g_value_init( &gvalue
, PANGO_TYPE_STYLE 
); 
2456                 g_value_set_enum( &gvalue
, PANGO_STYLE_ITALIC 
); 
2457                 g_object_set_property( G_OBJECT(renderer
), "style", &gvalue 
); 
2458                 g_value_unset( &gvalue 
); 
2465                 GValue gvalue 
= { 0, }; 
2466                 g_value_init( &gvalue
, PANGO_TYPE_WEIGHT 
); 
2467                 g_value_set_enum( &gvalue
, PANGO_WEIGHT_BOLD 
); 
2468                 g_object_set_property( G_OBJECT(renderer
), "weight", &gvalue 
); 
2469                 g_value_unset( &gvalue 
); 
2477             GValue gvalue 
= { 0, }; 
2478             g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
2479             g_value_set_boolean( &gvalue
, FALSE 
); 
2480             g_object_set_property( G_OBJECT(renderer
), "style-set", &gvalue 
); 
2481             g_value_unset( &gvalue 
); 
2486             GValue gvalue 
= { 0, }; 
2487             g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
2488             g_value_set_boolean( &gvalue
, FALSE 
); 
2489             g_object_set_property( G_OBJECT(renderer
), "weight-set", &gvalue 
); 
2490             g_value_unset( &gvalue 
); 
2495             GValue gvalue 
= { 0, }; 
2496             g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
2497             g_value_set_boolean( &gvalue
, FALSE 
); 
2498             g_object_set_property( G_OBJECT(renderer
), "foreground-set", &gvalue 
); 
2499             g_value_unset( &gvalue 
); 
2504     if (attr
.HasBackgroundColour()) 
2506         wxColour colour 
= attr
.GetBackgroundColour(); 
2507         const GdkColor 
* const gcol 
= colour
.GetColor(); 
2509         GValue gvalue 
= { 0, }; 
2510         g_value_init( &gvalue
, GDK_TYPE_COLOR 
); 
2511         g_value_set_boxed( &gvalue
, gcol 
); 
2512         g_object_set_property( G_OBJECT(renderer
), "cell-background_gdk", &gvalue 
); 
2513         g_value_unset( &gvalue 
); 
2517         GValue gvalue 
= { 0, }; 
2518         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
2519         g_value_set_boolean( &gvalue
, FALSE 
); 
2520         g_object_set_property( G_OBJECT(renderer
), "cell-background-set", &gvalue 
); 
2521         g_value_unset( &gvalue 
); 
2527 #include <wx/listimpl.cpp> 
2528 WX_DEFINE_LIST(wxDataViewColumnList
) 
2530 wxDataViewColumn::wxDataViewColumn( const wxString 
&title
, wxDataViewRenderer 
*cell
, 
2531                                     unsigned int model_column
, int width
, 
2532                                     wxAlignment align
, int flags 
) 
2533     : wxDataViewColumnBase( cell
, model_column 
) 
2535     Init( align
, flags
, width 
); 
2540 wxDataViewColumn::wxDataViewColumn( const wxBitmap 
&bitmap
, wxDataViewRenderer 
*cell
, 
2541                                     unsigned int model_column
, int width
, 
2542                                     wxAlignment align
, int flags 
) 
2543     : wxDataViewColumnBase( bitmap
, cell
, model_column 
) 
2545     Init( align
, flags
, width 
); 
2547     SetBitmap( bitmap 
); 
2550 void wxDataViewColumn::Init(wxAlignment align
, int flags
, int width
) 
2552     m_isConnected 
= false; 
2554     GtkCellRenderer 
*renderer 
= (GtkCellRenderer 
*) GetRenderer()->GetGtkHandle(); 
2555     GtkTreeViewColumn 
*column 
= gtk_tree_view_column_new(); 
2556     m_column 
= (GtkWidget
*) column
; 
2559     SetAlignment( align 
); 
2563     // Create container for icon and label 
2564     GtkWidget 
*box 
= gtk_hbox_new( FALSE
, 1 ); 
2565     gtk_widget_show( box 
); 
2566     // gtk_container_set_border_width((GtkContainer*)box, 2); 
2567     m_image 
= gtk_image_new(); 
2568     gtk_box_pack_start(GTK_BOX(box
), m_image
, FALSE
, FALSE
, 1); 
2569     m_label 
= gtk_label_new(""); 
2570     gtk_box_pack_end( GTK_BOX(box
), GTK_WIDGET(m_label
), FALSE
, FALSE
, 1 ); 
2571     gtk_tree_view_column_set_widget( column
, box 
); 
2573     gtk_tree_view_column_pack_end( column
, renderer
, TRUE 
); 
2575     gtk_tree_view_column_set_cell_data_func( column
, renderer
, 
2576         wxGtkTreeCellDataFunc
, (gpointer
) GetRenderer(), NULL 
); 
2579 void wxDataViewColumn::OnInternalIdle() 
2584     if (GTK_WIDGET_REALIZED(GetOwner()->m_treeview
)) 
2586         GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2589             g_signal_connect(column
->button
, "button_press_event", 
2590                       G_CALLBACK (gtk_dataview_header_button_press_callback
), this); 
2592             m_isConnected 
= true; 
2597 void wxDataViewColumn::SetOwner( wxDataViewCtrl 
*owner 
) 
2599     wxDataViewColumnBase::SetOwner( owner 
); 
2601     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2603     gtk_tree_view_column_set_title( column
, wxGTK_CONV_FONT(GetTitle(), GetOwner()->GetFont() ) ); 
2606 void wxDataViewColumn::SetTitle( const wxString 
&title 
) 
2608     wxDataViewCtrl 
*ctrl 
= GetOwner(); 
2609     gtk_label_set_text( GTK_LABEL(m_label
), ctrl 
? wxGTK_CONV_FONT(title
, ctrl
->GetFont()) 
2610                                                  : wxGTK_CONV_SYS(title
) ); 
2612         gtk_widget_hide( m_label 
); 
2614         gtk_widget_show( m_label 
); 
2617 wxString 
wxDataViewColumn::GetTitle() const 
2619     return wxGTK_CONV_BACK_FONT( 
2620             gtk_label_get_text( GTK_LABEL(m_label
) ), 
2621             GetOwner()->GetFont() 
2625 void wxDataViewColumn::SetBitmap( const wxBitmap 
&bitmap 
) 
2627     wxDataViewColumnBase::SetBitmap( bitmap 
); 
2631         GtkImage 
*gtk_image 
= GTK_IMAGE(m_image
); 
2633         GdkBitmap 
*mask 
= NULL
; 
2634         if (bitmap
.GetMask()) 
2635             mask 
= bitmap
.GetMask()->GetBitmap(); 
2637         if (bitmap
.HasPixbuf()) 
2639             gtk_image_set_from_pixbuf(GTK_IMAGE(gtk_image
), 
2640                                       bitmap
.GetPixbuf()); 
2644             gtk_image_set_from_pixmap(GTK_IMAGE(gtk_image
), 
2645                                       bitmap
.GetPixmap(), mask
); 
2647         gtk_widget_show( m_image 
); 
2651         gtk_widget_hide( m_image 
); 
2655 void wxDataViewColumn::SetHidden( bool hidden 
) 
2657     gtk_tree_view_column_set_visible( GTK_TREE_VIEW_COLUMN(m_column
), !hidden 
); 
2660 void wxDataViewColumn::SetResizeable( bool resizeable 
) 
2662     gtk_tree_view_column_set_resizable( GTK_TREE_VIEW_COLUMN(m_column
), resizeable 
); 
2665 void wxDataViewColumn::SetAlignment( wxAlignment align 
) 
2667     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2669     gfloat xalign 
= 0.0; 
2670     if (align 
== wxALIGN_RIGHT
) 
2672     if (align 
== wxALIGN_CENTER_HORIZONTAL 
|| 
2673         align 
== wxALIGN_CENTER
) 
2676     gtk_tree_view_column_set_alignment( column
, xalign 
); 
2678     if (m_renderer 
&& m_renderer
->GetAlignment() == -1) 
2679         m_renderer
->GtkUpdateAlignment(); 
2682 wxAlignment 
wxDataViewColumn::GetAlignment() const 
2684     gfloat xalign 
= gtk_tree_view_column_get_alignment( GTK_TREE_VIEW_COLUMN(m_column
) ); 
2687         return wxALIGN_RIGHT
; 
2689         return wxALIGN_CENTER_HORIZONTAL
; 
2691     return wxALIGN_LEFT
; 
2694 void wxDataViewColumn::SetSortable( bool sortable 
) 
2696     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2700         gtk_tree_view_column_set_sort_column_id( column
, GetModelColumn() ); 
2704         gtk_tree_view_column_set_sort_column_id( column
, -1 ); 
2705         gtk_tree_view_column_set_sort_indicator( column
, FALSE 
); 
2706         gtk_tree_view_column_set_clickable( column
, FALSE 
); 
2710 bool wxDataViewColumn::IsSortable() const 
2712     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2713     return gtk_tree_view_column_get_clickable( column 
); 
2716 void wxDataViewColumn::SetAsSortKey( bool WXUNUSED(sort
) ) 
2718     // it might not make sense to have this function in wxHeaderColumn at 
2719     // all in fact, changing of the sort order should only be done using the 
2720     // associated control API 
2721     wxFAIL_MSG( "not implemented" ); 
2724 bool wxDataViewColumn::IsSortKey() const 
2726     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2727     return gtk_tree_view_column_get_sort_indicator( column 
); 
2730 bool wxDataViewColumn::IsResizeable() const 
2732     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2733     return gtk_tree_view_column_get_resizable( column 
); 
2736 bool wxDataViewColumn::IsHidden() const 
2738     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2739     return !gtk_tree_view_column_get_visible( column 
); 
2742 void wxDataViewColumn::SetSortOrder( bool ascending 
) 
2744     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2747         gtk_tree_view_column_set_sort_order( column
, GTK_SORT_ASCENDING 
); 
2749         gtk_tree_view_column_set_sort_order( column
, GTK_SORT_DESCENDING 
); 
2751     gtk_tree_view_column_set_sort_indicator( column
, TRUE 
); 
2754 bool wxDataViewColumn::IsSortOrderAscending() const 
2756     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2758     return (gtk_tree_view_column_get_sort_order( column 
) != GTK_SORT_DESCENDING
); 
2761 void wxDataViewColumn::SetMinWidth( int width 
) 
2763     gtk_tree_view_column_set_min_width( GTK_TREE_VIEW_COLUMN(m_column
), width 
); 
2766 int wxDataViewColumn::GetMinWidth() const 
2768     return gtk_tree_view_column_get_min_width( GTK_TREE_VIEW_COLUMN(m_column
) ); 
2771 int wxDataViewColumn::GetWidth() const 
2773     return gtk_tree_view_column_get_width( GTK_TREE_VIEW_COLUMN(m_column
) ); 
2776 void wxDataViewColumn::SetWidth( int width 
) 
2781         gtk_tree_view_column_set_sizing( GTK_TREE_VIEW_COLUMN(m_column
), GTK_TREE_VIEW_COLUMN_FIXED 
); 
2783         // TODO find a better calculation 
2784         gtk_tree_view_column_set_fixed_width( GTK_TREE_VIEW_COLUMN(m_column
), wxDVC_DEFAULT_WIDTH 
); 
2786         // this is unpractical for large numbers of items and disables 
2787         // user resizing, which is totally unexpected 
2788         gtk_tree_view_column_set_sizing( GTK_TREE_VIEW_COLUMN(m_column
), GTK_TREE_VIEW_COLUMN_AUTOSIZE 
); 
2793         gtk_tree_view_column_set_sizing( GTK_TREE_VIEW_COLUMN(m_column
), GTK_TREE_VIEW_COLUMN_FIXED 
); 
2795         gtk_tree_view_column_set_fixed_width( GTK_TREE_VIEW_COLUMN(m_column
), width 
); 
2799 void wxDataViewColumn::SetReorderable( bool reorderable 
) 
2801     gtk_tree_view_column_set_reorderable( GTK_TREE_VIEW_COLUMN(m_column
), reorderable 
); 
2804 bool wxDataViewColumn::IsReorderable() const 
2806     return gtk_tree_view_column_get_reorderable( GTK_TREE_VIEW_COLUMN(m_column
) ); 
2809 //----------------------------------------------------------------------------- 
2810 // wxGtkTreeModelNode 
2811 //----------------------------------------------------------------------------- 
2813 void wxGtkTreeModelNode::Resort() 
2815     size_t child_count 
= GetChildCount(); 
2816     if (child_count 
== 0) 
2819     size_t node_count 
= GetNodesCount(); 
2821     if (child_count 
== 1) 
2823         if (node_count 
== 1) 
2825             wxGtkTreeModelNode 
*node 
= m_nodes
.Item( 0 ); 
2831     wxGtkTreeModelChildren temp
; 
2832     WX_APPEND_ARRAY( temp
, m_children 
); 
2834     g_internal 
= m_internal
; 
2835     m_children
.Sort( &wxGtkTreeModelChildCmp 
); 
2837     gint 
*new_order 
= new gint
[child_count
]; 
2840     for (pos 
= 0; pos 
< child_count
; pos
++) 
2842         void *id 
= m_children
.Item( pos 
); 
2843         int old_pos 
= temp
.Index( id 
); 
2844         new_order
[pos
] = old_pos
; 
2847     GtkTreeModel 
*gtk_tree_model 
= GTK_TREE_MODEL( m_internal
->GetGtkModel() ); 
2850     iter
.user_data 
= GetItem().GetID(); 
2851     iter
.stamp 
= m_internal
->GetGtkModel()->stamp
; 
2853     GtkTreePath 
*path 
= m_internal
->get_path( &iter 
); 
2855     gtk_tree_model_rows_reordered( gtk_tree_model
, path
, &iter
, new_order 
); 
2857     gtk_tree_path_free (path
); 
2859     delete [] new_order
; 
2861     for (pos 
= 0; pos 
< node_count
; pos
++) 
2863         wxGtkTreeModelNode 
*node 
= m_nodes
.Item( pos 
); 
2868 //----------------------------------------------------------------------------- 
2869 // wxDataViewCtrlInternal 
2870 //----------------------------------------------------------------------------- 
2872 wxDataViewCtrlInternal::wxDataViewCtrlInternal( wxDataViewCtrl 
*owner
, 
2873     wxDataViewModel 
*wx_model
, GtkWxTreeModel 
*gtk_model 
) 
2876     m_wx_model 
= wx_model
; 
2877     m_gtk_model 
= gtk_model
; 
2879     m_sort_order 
= GTK_SORT_ASCENDING
; 
2881     m_dataview_sort_column 
= NULL
; 
2883     m_dragDataObject 
= NULL
; 
2884     m_dropDataObject 
= NULL
; 
2886     if (!m_wx_model
->IsVirtualListModel()) 
2890 wxDataViewCtrlInternal::~wxDataViewCtrlInternal() 
2892     g_object_unref( m_gtk_model 
); 
2894     delete m_dragDataObject
; 
2895     delete m_dropDataObject
; 
2898 void wxDataViewCtrlInternal::InitTree() 
2900     wxDataViewItem item
; 
2901     m_root 
= new wxGtkTreeModelNode( NULL
, item
, this ); 
2903     BuildBranch( m_root 
); 
2906 void wxDataViewCtrlInternal::BuildBranch( wxGtkTreeModelNode 
*node 
) 
2908     if (node
->GetChildCount() == 0) 
2910         wxDataViewItemArray children
; 
2911         unsigned int count 
= m_wx_model
->GetChildren( node
->GetItem(), children 
); 
2913         for (pos 
= 0; pos 
< count
; pos
++) 
2915             wxDataViewItem child 
= children
[pos
]; 
2917             if (m_wx_model
->IsContainer( child 
)) 
2918                 node
->AddNode( new wxGtkTreeModelNode( node
, child
, this ) ); 
2920                 node
->AddLeave( child
.GetID() ); 
2922             // Don't send any events here 
2929 bool wxDataViewCtrlInternal::EnableDragSource( const wxDataFormat 
&format 
) 
2931     wxGtkString 
atom_str( gdk_atom_name( format  
) ); 
2932     m_dragSourceTargetEntryTarget 
= wxCharBuffer( atom_str 
); 
2934     m_dragSourceTargetEntry
.target 
=  m_dragSourceTargetEntryTarget
.data(); 
2935     m_dragSourceTargetEntry
.flags 
= 0; 
2936     m_dragSourceTargetEntry
.info 
= static_cast<guint
>(-1); 
2938     gtk_tree_view_enable_model_drag_source( GTK_TREE_VIEW(m_owner
->GtkGetTreeView() ), 
2939        GDK_BUTTON1_MASK
, &m_dragSourceTargetEntry
, 1, (GdkDragAction
) GDK_ACTION_COPY 
); 
2944 gboolean 
wxDataViewCtrlInternal::row_draggable( GtkTreeDragSource 
*WXUNUSED(drag_source
), 
2947     delete m_dragDataObject
; 
2950     if (!get_iter( &iter
, path 
)) return FALSE
; 
2951     wxDataViewItem 
item( (void*) iter
.user_data 
); 
2953     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_BEGIN_DRAG
, m_owner
->GetId() ); 
2954     event
.SetItem( item 
); 
2955     event
.SetModel( m_wx_model 
); 
2956     if (!m_owner
->HandleWindowEvent( event 
)) 
2959     if (!event
.IsAllowed()) 
2962     wxDataObject 
*obj 
= event
.GetDataObject(); 
2966     m_dragDataObject 
= obj
; 
2972 wxDataViewCtrlInternal::drag_data_delete(GtkTreeDragSource 
*WXUNUSED(drag_source
), 
2973                                          GtkTreePath 
*WXUNUSED(path
)) 
2978 gboolean 
wxDataViewCtrlInternal::drag_data_get( GtkTreeDragSource 
*WXUNUSED(drag_source
), 
2979     GtkTreePath 
*path
, GtkSelectionData 
*selection_data 
) 
2982     if (!get_iter( &iter
, path 
)) return FALSE
; 
2983     wxDataViewItem 
item( (void*) iter
.user_data 
); 
2985     if (!m_dragDataObject
->IsSupported( selection_data
->target 
)) 
2988     size_t size 
= m_dragDataObject
->GetDataSize( selection_data
->target 
); 
2992     void *buf 
= malloc( size 
); 
2994     gboolean res 
= FALSE
; 
2995     if (m_dragDataObject
->GetDataHere( selection_data
->target
, buf 
)) 
2999         gtk_selection_data_set( selection_data
, selection_data
->target
, 
3000             8, (const guchar
*) buf
, size 
); 
3009 wxDataViewCtrlInternal::drag_data_received(GtkTreeDragDest 
*WXUNUSED(drag_dest
), 
3010                                            GtkTreePath 
*WXUNUSED(dest
), 
3011                                            GtkSelectionData 
*WXUNUSED(selection_data
)) 
3017 wxDataViewCtrlInternal::row_drop_possible(GtkTreeDragDest 
*WXUNUSED(drag_dest
), 
3018                                           GtkTreePath 
*WXUNUSED(dest_path
), 
3019                                           GtkSelectionData 
*WXUNUSED(selection_data
)) 
3024 // notifications from wxDataViewModel 
3026 bool wxDataViewCtrlInternal::Cleared() 
3034     // Create new GTK model 
3035     g_object_unref( m_gtk_model 
); 
3036     m_gtk_model 
= wxgtk_tree_model_new(); 
3037     m_gtk_model
->internal 
= this; 
3042 void wxDataViewCtrlInternal::Resort() 
3044     if (!m_wx_model
->IsVirtualListModel()) 
3048 bool wxDataViewCtrlInternal::ItemAdded( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
) 
3050     if (!m_wx_model
->IsVirtualListModel()) 
3052         wxGtkTreeModelNode 
*parent_node 
= FindNode( parent 
); 
3053         if (m_wx_model
->IsContainer( item 
)) 
3054             parent_node
->AddNode( new wxGtkTreeModelNode( parent_node
, item
, this ) ); 
3056             parent_node
->AddLeave( item
.GetID() ); 
3062 bool wxDataViewCtrlInternal::ItemDeleted( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
) 
3064     if (!m_wx_model
->IsVirtualListModel()) 
3066         wxGtkTreeModelNode 
*parent_node 
= FindNode( parent 
); 
3067         parent_node
->DeleteChild( item
.GetID() ); 
3073 bool wxDataViewCtrlInternal::ItemChanged( const wxDataViewItem 
&item 
) 
3075     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED
, m_owner
->GetId() ); 
3076     event
.SetEventObject( m_owner 
); 
3077     event
.SetModel( m_owner
->GetModel() ); 
3078     event
.SetItem( item 
); 
3079     m_owner
->HandleWindowEvent( event 
); 
3084 bool wxDataViewCtrlInternal::ValueChanged( const wxDataViewItem 
&item
, unsigned int col 
) 
3086     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED
, m_owner
->GetId() ); 
3087     event
.SetEventObject( m_owner 
); 
3088     event
.SetModel( m_owner
->GetModel() ); 
3089     event
.SetColumn( col 
); 
3090     event
.SetDataViewColumn( GetOwner()->GetColumn(col
) ); 
3091     event
.SetItem( item 
); 
3092     m_owner
->HandleWindowEvent( event 
); 
3099 GtkTreeModelFlags 
wxDataViewCtrlInternal::get_flags() 
3101     if (m_wx_model
->IsVirtualListModel()) 
3102         return GTK_TREE_MODEL_LIST_ONLY
; 
3104         return GTK_TREE_MODEL_ITERS_PERSIST
; 
3107 gboolean 
wxDataViewCtrlInternal::get_iter( GtkTreeIter 
*iter
, GtkTreePath 
*path 
) 
3109     if (m_wx_model
->IsVirtualListModel()) 
3111         wxDataViewIndexListModel 
*wx_model 
= (wxDataViewIndexListModel
*) m_wx_model
; 
3113         unsigned int i 
= (unsigned int)gtk_tree_path_get_indices (path
)[0]; 
3115         if (i 
>= wx_model
->GetLastIndex() + 1) 
3118         iter
->stamp 
= m_gtk_model
->stamp
; 
3119         // user_data is just the index 
3120         iter
->user_data 
= (gpointer
) i
; 
3126         int depth 
= gtk_tree_path_get_depth( path 
); 
3128         wxGtkTreeModelNode 
*node 
= m_root
; 
3131         for (i 
= 0; i 
< depth
; i
++) 
3133             BuildBranch( node 
); 
3135             gint pos 
= gtk_tree_path_get_indices (path
)[i
]; 
3136             if (pos 
< 0) return FALSE
; 
3137             if ((size_t)pos 
>= node
->GetChildCount()) return FALSE
; 
3139             void* id 
= node
->GetChildren().Item( (size_t) pos 
); 
3143                 iter
->stamp 
= m_gtk_model
->stamp
; 
3144                 iter
->user_data 
= id
; 
3148             size_t count 
= node
->GetNodes().GetCount(); 
3150             for (pos2 
= 0; pos2 
< count
; pos2
++) 
3152                 wxGtkTreeModelNode 
*child_node 
= node
->GetNodes().Item( pos2 
); 
3153                 if (child_node
->GetItem().GetID() == id
) 
3165 GtkTreePath 
*wxDataViewCtrlInternal::get_path( GtkTreeIter 
*iter 
) 
3167     GtkTreePath 
*retval 
= gtk_tree_path_new (); 
3169     if (m_wx_model
->IsVirtualListModel()) 
3171         // user_data is just the index 
3172         int i 
= (wxUIntPtr
) iter
->user_data
; 
3173         gtk_tree_path_append_index (retval
, i
); 
3177         void *id 
= iter
->user_data
; 
3179         wxGtkTreeModelNode 
*node 
= FindParentNode( iter 
); 
3182             int pos 
= node
->GetChildren().Index( id 
); 
3184             gtk_tree_path_prepend_index( retval
, pos 
); 
3186             id 
= node
->GetItem().GetID(); 
3187             node 
= node
->GetParent(); 
3194 gboolean 
wxDataViewCtrlInternal::iter_next( GtkTreeIter 
*iter 
) 
3196     if (m_wx_model
->IsVirtualListModel()) 
3198         wxDataViewIndexListModel 
*wx_model 
= (wxDataViewIndexListModel
*) m_wx_model
; 
3200         int n 
= (wxUIntPtr
) iter
->user_data
; 
3205         if (n 
>= (int) wx_model
->GetLastIndex()) 
3208         iter
->user_data 
= (gpointer
) ++n
; 
3212         wxGtkTreeModelNode 
*parent 
= FindParentNode( iter 
); 
3213         if( parent 
== NULL 
) 
3216         int pos 
= parent
->GetChildren().Index( iter
->user_data 
); 
3218         if (pos 
== (int) parent
->GetChildCount()-1) 
3221         iter
->stamp 
= m_gtk_model
->stamp
; 
3222         iter
->user_data 
= parent
->GetChildren().Item( pos
+1 ); 
3228 gboolean 
wxDataViewCtrlInternal::iter_children( GtkTreeIter 
*iter
, GtkTreeIter 
*parent 
) 
3230     if (m_wx_model
->IsVirtualListModel()) 
3232         // this is a list, nodes have no children 
3236         iter
->stamp 
= m_gtk_model
->stamp
; 
3237         iter
->user_data 
= (gpointer
) -1; 
3243         wxDataViewItem 
item( (void*) parent
->user_data 
); 
3245         if (!m_wx_model
->IsContainer( item 
)) 
3248         wxGtkTreeModelNode 
*parent_node 
= FindNode( parent 
); 
3249         BuildBranch( parent_node 
); 
3251         if (parent_node
->GetChildCount() == 0) 
3254         iter
->stamp 
= m_gtk_model
->stamp
; 
3255         iter
->user_data 
= (gpointer
) parent_node
->GetChildren().Item( 0 ); 
3261 gboolean 
wxDataViewCtrlInternal::iter_has_child( GtkTreeIter 
*iter 
) 
3263     if (m_wx_model
->IsVirtualListModel()) 
3265         // this is a list, nodes have no children 
3270         wxDataViewItem 
item( (void*) iter
->user_data 
); 
3272         bool is_container 
= m_wx_model
->IsContainer( item 
); 
3277         wxGtkTreeModelNode 
*node 
= FindNode( iter 
); 
3278         BuildBranch( node 
); 
3280         return (node
->GetChildCount() > 0); 
3284 gint 
wxDataViewCtrlInternal::iter_n_children( GtkTreeIter 
*iter 
) 
3286     if (m_wx_model
->IsVirtualListModel()) 
3288         wxDataViewIndexListModel 
*wx_model 
= (wxDataViewIndexListModel
*) m_wx_model
; 
3291             return (gint
) wx_model
->GetLastIndex() + 1; 
3297         wxDataViewItem 
item( (void*) iter
->user_data 
); 
3299         if (!m_wx_model
->IsContainer( item 
)) 
3302         wxGtkTreeModelNode 
*parent_node 
= FindNode( iter 
); 
3303         BuildBranch( parent_node 
); 
3305         // wxPrintf( "iter_n_children %d\n", parent_node->GetChildCount() ); 
3307         return parent_node
->GetChildCount(); 
3311 gboolean 
wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter 
*iter
, GtkTreeIter 
*parent
, gint n 
) 
3313     if (m_wx_model
->IsVirtualListModel()) 
3315         wxDataViewIndexListModel 
*wx_model 
= (wxDataViewIndexListModel
*) m_wx_model
; 
3323         if (n 
>= (gint
) wx_model
->GetLastIndex() + 1) 
3326         iter
->stamp 
= m_gtk_model
->stamp
; 
3327         iter
->user_data 
= (gpointer
) n
; 
3334         if (parent
) id 
= (void*) parent
->user_data
; 
3335         wxDataViewItem 
item( id 
); 
3337         if (!m_wx_model
->IsContainer( item 
)) 
3340         wxGtkTreeModelNode 
*parent_node 
= FindNode( parent 
); 
3341         BuildBranch( parent_node 
); 
3343         // wxPrintf( "iter_nth_child %d\n", n ); 
3345         iter
->stamp 
= m_gtk_model
->stamp
; 
3346         iter
->user_data 
= parent_node
->GetChildren().Item( n 
); 
3352 gboolean 
wxDataViewCtrlInternal::iter_parent( GtkTreeIter 
*iter
, GtkTreeIter 
*child 
) 
3354     if (m_wx_model
->IsVirtualListModel()) 
3360         wxGtkTreeModelNode 
*node 
= FindParentNode( child 
); 
3364         iter
->stamp 
= m_gtk_model
->stamp
; 
3365         iter
->user_data 
= (gpointer
) node
->GetItem().GetID(); 
3371 static wxGtkTreeModelNode
* 
3372 wxDataViewCtrlInternal_FindNode( wxDataViewModel 
* model
, wxGtkTreeModelNode 
*treeNode
, const wxDataViewItem 
&item 
) 
3378     list
.DeleteContents( true ); 
3379     wxDataViewItem 
it( item 
); 
3383         wxDataViewItem 
* pItem 
= new wxDataViewItem( it 
); 
3384         list
.Insert( pItem 
); 
3385         it 
= model
->GetParent( it 
); 
3388     wxGtkTreeModelNode 
* node 
= treeNode
; 
3389     for( ItemList::compatibility_iterator n 
= list
.GetFirst(); n
; n 
= n
->GetNext() ) 
3391         if( node 
&& node
->GetNodes().GetCount() != 0 ) 
3393             int len 
= node
->GetNodes().GetCount(); 
3394             wxGtkTreeModelNodes nodes 
= node
->GetNodes(); 
3396             for( ; j 
< len
; j 
++) 
3398                 if( nodes
[j
]->GetItem() == *(n
->GetData())) 
3417 wxGtkTreeModelNode 
*wxDataViewCtrlInternal::FindNode( GtkTreeIter 
*iter 
) 
3422     wxDataViewItem 
item( (void*) iter
->user_data 
); 
3426     wxGtkTreeModelNode 
*result 
= wxDataViewCtrlInternal_FindNode( m_wx_model
, m_root
, item 
); 
3430         wxLogDebug( "Not found %p", iter
->user_data 
); 
3438 wxGtkTreeModelNode 
*wxDataViewCtrlInternal::FindNode( const wxDataViewItem 
&item 
) 
3443     wxGtkTreeModelNode 
*result 
= wxDataViewCtrlInternal_FindNode( m_wx_model
, m_root
, item 
); 
3447         wxLogDebug( "Not found %p", item
.GetID() ); 
3455 static wxGtkTreeModelNode
* 
3456 wxDataViewCtrlInternal_FindParentNode( wxDataViewModel 
* model
, wxGtkTreeModelNode 
*treeNode
, const wxDataViewItem 
&item 
) 
3462     list
.DeleteContents( true ); 
3466     wxDataViewItem 
it( model
->GetParent( item 
) ); 
3469         wxDataViewItem 
* pItem 
= new wxDataViewItem( it 
); 
3470         list
.Insert( pItem 
); 
3471         it 
= model
->GetParent( it 
); 
3474     wxGtkTreeModelNode 
* node 
= treeNode
; 
3475     for( ItemList::compatibility_iterator n 
= list
.GetFirst(); n
; n 
= n
->GetNext() ) 
3477         if( node 
&& node
->GetNodes().GetCount() != 0 ) 
3479             int len 
= node
->GetNodes().GetCount(); 
3480             wxGtkTreeModelNodes nodes 
= node
->GetNodes(); 
3482             for( ; j 
< len
; j 
++) 
3484                 if( nodes
[j
]->GetItem() == *(n
->GetData())) 
3499     //Examine whether the node is item's parent node 
3500     int len 
= node
->GetChildCount(); 
3501     for( int i 
= 0; i 
< len 
; i 
++ ) 
3503         if( node
->GetChildren().Item( i 
) == item
.GetID() ) 
3509 wxGtkTreeModelNode 
*wxDataViewCtrlInternal::FindParentNode( GtkTreeIter 
*iter 
) 
3514     wxDataViewItem 
item( (void*) iter
->user_data 
); 
3518     return wxDataViewCtrlInternal_FindParentNode( m_wx_model
, m_root
, item 
); 
3521 wxGtkTreeModelNode 
*wxDataViewCtrlInternal::FindParentNode( const wxDataViewItem 
&item 
) 
3526     return wxDataViewCtrlInternal_FindParentNode( m_wx_model
, m_root
, item 
); 
3529 //----------------------------------------------------------------------------- 
3530 // wxDataViewCtrl signal callbacks 
3531 //----------------------------------------------------------------------------- 
3534 wxdataview_selection_changed_callback( GtkTreeSelection
* WXUNUSED(selection
), wxDataViewCtrl 
*dv 
) 
3536     if (!GTK_WIDGET_REALIZED(dv
->m_widget
)) 
3539     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED
, dv
->GetId() ); 
3540     event
.SetItem( dv
->GetSelection() ); 
3541     event
.SetModel( dv
->GetModel() ); 
3542     dv
->HandleWindowEvent( event 
); 
3546 wxdataview_row_activated_callback( GtkTreeView
* WXUNUSED(treeview
), GtkTreePath 
*path
, 
3547                                    GtkTreeViewColumn 
*WXUNUSED(column
), wxDataViewCtrl 
*dv 
) 
3549     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED
, dv
->GetId() ); 
3552     dv
->GtkGetInternal()->get_iter( &iter
, path 
); 
3553     wxDataViewItem 
item( (void*) iter
.user_data 
);; 
3554     event
.SetItem( item 
); 
3555     event
.SetModel( dv
->GetModel() ); 
3556     dv
->HandleWindowEvent( event 
); 
3560 wxdataview_test_expand_row_callback( GtkTreeView
* WXUNUSED(treeview
), GtkTreeIter
* iter
, 
3561                                      GtkTreePath 
*WXUNUSED(path
), wxDataViewCtrl 
*dv 
) 
3563     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING
, dv
->GetId() ); 
3565     wxDataViewItem 
item( (void*) iter
->user_data 
);; 
3566     event
.SetItem( item 
); 
3567     event
.SetModel( dv
->GetModel() ); 
3568     dv
->HandleWindowEvent( event 
); 
3570     return !event
.IsAllowed(); 
3574 wxdataview_row_expanded_callback( GtkTreeView
* WXUNUSED(treeview
), GtkTreeIter
* iter
, 
3575                                   GtkTreePath 
*WXUNUSED(path
), wxDataViewCtrl 
*dv 
) 
3577     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDED
, dv
->GetId() ); 
3579     wxDataViewItem 
item( (void*) iter
->user_data 
);; 
3580     event
.SetItem( item 
); 
3581     event
.SetModel( dv
->GetModel() ); 
3582     dv
->HandleWindowEvent( event 
); 
3586 wxdataview_test_collapse_row_callback( GtkTreeView
* WXUNUSED(treeview
), GtkTreeIter
* iter
, 
3587                                        GtkTreePath 
*WXUNUSED(path
), wxDataViewCtrl 
*dv 
) 
3589     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSING
, dv
->GetId() ); 
3591     wxDataViewItem 
item( (void*) iter
->user_data 
);; 
3592     event
.SetItem( item 
); 
3593     event
.SetModel( dv
->GetModel() ); 
3594     dv
->HandleWindowEvent( event 
); 
3596     return !event
.IsAllowed(); 
3600 wxdataview_row_collapsed_callback( GtkTreeView
* WXUNUSED(treeview
), GtkTreeIter
* iter
, 
3601                                    GtkTreePath 
*WXUNUSED(path
), wxDataViewCtrl 
*dv 
) 
3603     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSED
, dv
->GetId() ); 
3605     wxDataViewItem 
item( (void*) iter
->user_data 
);; 
3606     event
.SetItem( item 
); 
3607     event
.SetModel( dv
->GetModel() ); 
3608     dv
->HandleWindowEvent( event 
); 
3611 //----------------------------------------------------------------------------- 
3613 //----------------------------------------------------------------------------- 
3615 void wxDataViewCtrl::AddChildGTK(wxWindowGTK
* child
) 
3617     GtkWidget
* treeview 
= GtkGetTreeView(); 
3619     // Insert widget in GtkTreeView 
3620     if (GTK_WIDGET_REALIZED(treeview
)) 
3621         gtk_widget_set_parent_window( child
->m_widget
, 
3622           gtk_tree_view_get_bin_window( GTK_TREE_VIEW(treeview
) ) ); 
3623     gtk_widget_set_parent( child
->m_widget
, treeview 
); 
3627 void gtk_dataviewctrl_size_callback( GtkWidget 
*WXUNUSED(widget
), 
3628                                      GtkAllocation 
*WXUNUSED(gtk_alloc
), 
3629                                      wxDataViewCtrl 
*win 
) 
3631     wxWindowList::compatibility_iterator node 
= win
->GetChildren().GetFirst(); 
3634         wxWindow 
*child 
= node
->GetData(); 
3637         gtk_widget_size_request( child
->m_widget
, &req 
); 
3639         GtkAllocation alloc
; 
3640         alloc
.x 
= child
->m_x
; 
3641         alloc
.y 
= child
->m_y
; 
3642         alloc
.width 
= child
->m_width
; 
3643         alloc
.height 
= child
->m_height
; 
3644         gtk_widget_size_allocate( child
->m_widget
, &alloc 
); 
3646         node 
= node
->GetNext(); 
3651 //----------------------------------------------------------------------------- 
3652 // "motion_notify_event" 
3653 //----------------------------------------------------------------------------- 
3656 gtk_dataview_motion_notify_callback( GtkWidget 
*WXUNUSED(widget
), 
3657                                      GdkEventMotion 
*gdk_event
, 
3658                                      wxDataViewCtrl 
*dv 
) 
3660     if (gdk_event
->is_hint
) 
3664         GdkModifierType state
; 
3665         gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
3670     GtkTreePath 
*path 
= NULL
; 
3671     GtkTreeViewColumn 
*column 
= NULL
; 
3674     if (gtk_tree_view_get_path_at_pos( 
3675         GTK_TREE_VIEW(dv
->GtkGetTreeView()), 
3676         (int) gdk_event
->x
, (int) gdk_event
->y
, 
3685             dv
->GtkGetInternal()->get_iter( &iter
, path 
); 
3687             // wxPrintf( "mouse %d %d\n", (int) gdk_event->x, (int) gdk_event->y ); 
3689             gtk_tree_path_free( path 
); 
3697 //----------------------------------------------------------------------------- 
3698 // "button_press_event" 
3699 //----------------------------------------------------------------------------- 
3702 gtk_dataview_button_press_callback( GtkWidget 
*WXUNUSED(widget
), 
3703                                     GdkEventButton 
*gdk_event
, 
3704                                     wxDataViewCtrl 
*dv 
) 
3706     if ((gdk_event
->button 
== 3) && (gdk_event
->type 
== GDK_BUTTON_PRESS
)) 
3708         GtkTreePath 
*path 
= NULL
; 
3709         GtkTreeViewColumn 
*column 
= NULL
; 
3712         if (gtk_tree_view_get_path_at_pos( 
3713             GTK_TREE_VIEW(dv
->GtkGetTreeView()), 
3714             (int) gdk_event
->x
, (int) gdk_event
->y
, 
3723                 dv
->GtkGetInternal()->get_iter( &iter
, path 
); 
3725                 wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU
, dv
->GetId() ); 
3726                 wxDataViewItem 
item( (void*) iter
.user_data 
);; 
3727                 event
.SetItem( item 
); 
3728                 event
.SetModel( dv
->GetModel() ); 
3729                 bool ret 
= dv
->HandleWindowEvent( event 
); 
3730                 gtk_tree_path_free( path 
); 
3739 IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl
, wxDataViewCtrlBase
) 
3741 wxDataViewCtrl::~wxDataViewCtrl() 
3744         GetModel()->RemoveNotifier( m_notifier 
); 
3748     // remove the model from the GtkTreeView before it gets destroyed by the 
3749     // wxDataViewCtrlBase's dtor 
3750     gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview
), NULL 
); 
3755 void wxDataViewCtrl::Init() 
3760     m_cols
.DeleteContents( true ); 
3763 bool wxDataViewCtrl::Create(wxWindow 
*parent
, wxWindowID id
, 
3764            const wxPoint
& pos
, const wxSize
& size
, 
3765            long style
, const wxValidator
& validator 
) 
3769     if (!PreCreation( parent
, pos
, size 
) || 
3770         !CreateBase( parent
, id
, pos
, size
, style
, validator 
)) 
3772         wxFAIL_MSG( wxT("wxDataViewCtrl creation failed") ); 
3776     m_widget 
= gtk_scrolled_window_new (NULL
, NULL
); 
3777     g_object_ref(m_widget
); 
3779     GtkScrolledWindowSetBorder(m_widget
, style
); 
3781     m_treeview 
= gtk_tree_view_new(); 
3782     gtk_container_add (GTK_CONTAINER (m_widget
), m_treeview
); 
3784     g_signal_connect (m_treeview
, "size_allocate", 
3785                      G_CALLBACK (gtk_dataviewctrl_size_callback
), this); 
3788     if (!gtk_check_version(2,6,0)) 
3790         bool fixed 
= (style 
& wxDV_VARIABLE_LINE_HEIGHT
) == 0; 
3791         gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview
), fixed 
); 
3795     if (style 
& wxDV_MULTIPLE
) 
3797         GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
3798         gtk_tree_selection_set_mode( selection
, GTK_SELECTION_MULTIPLE 
); 
3801     gtk_tree_view_set_headers_visible( GTK_TREE_VIEW(m_treeview
), (style 
& wxDV_NO_HEADER
) == 0 ); 
3804     if (!gtk_check_version(2,10,0)) 
3806         GtkTreeViewGridLines grid 
= GTK_TREE_VIEW_GRID_LINES_NONE
; 
3808         if ((style 
& wxDV_HORIZ_RULES
) != 0 && 
3809             (style 
& wxDV_VERT_RULES
) != 0) 
3810             grid 
= GTK_TREE_VIEW_GRID_LINES_BOTH
; 
3811         else if (style 
& wxDV_VERT_RULES
) 
3812             grid 
= GTK_TREE_VIEW_GRID_LINES_VERTICAL
; 
3813         else if (style 
& wxDV_HORIZ_RULES
) 
3814             grid 
= GTK_TREE_VIEW_GRID_LINES_HORIZONTAL
; 
3816         if (grid 
!= GTK_TREE_VIEW_GRID_LINES_NONE
) 
3817             gtk_tree_view_set_grid_lines( GTK_TREE_VIEW(m_treeview
), grid 
); 
3821     gtk_tree_view_set_rules_hint( GTK_TREE_VIEW(m_treeview
), (style 
& wxDV_ROW_LINES
) != 0 ); 
3823     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_widget
), 
3824         GTK_POLICY_AUTOMATIC
, GTK_POLICY_ALWAYS
); 
3825     gtk_widget_show (m_treeview
); 
3827     m_parent
->DoAddChild( this ); 
3831     GtkEnableSelectionEvents(); 
3833     g_signal_connect_after (m_treeview
, "row-activated", 
3834                             G_CALLBACK (wxdataview_row_activated_callback
), this); 
3836     g_signal_connect (m_treeview
, "test-collapse-row", 
3837                             G_CALLBACK (wxdataview_test_collapse_row_callback
), this); 
3839     g_signal_connect_after (m_treeview
, "row-collapsed", 
3840                             G_CALLBACK (wxdataview_row_collapsed_callback
), this); 
3842     g_signal_connect (m_treeview
, "test-expand-row", 
3843                             G_CALLBACK (wxdataview_test_expand_row_callback
), this); 
3845     g_signal_connect_after (m_treeview
, "row-expanded", 
3846                             G_CALLBACK (wxdataview_row_expanded_callback
), this); 
3848     g_signal_connect (m_treeview
, "motion_notify_event", 
3849                       G_CALLBACK (gtk_dataview_motion_notify_callback
), this); 
3851     g_signal_connect (m_treeview
, "button_press_event", 
3852                       G_CALLBACK (gtk_dataview_button_press_callback
), this); 
3857 void wxDataViewCtrl::OnInternalIdle() 
3859     wxWindow::OnInternalIdle(); 
3861     unsigned int cols 
= GetColumnCount(); 
3863     for (i 
= 0; i 
< cols
; i
++) 
3865         wxDataViewColumn 
*col 
= GetColumn( i 
); 
3866         col
->OnInternalIdle(); 
3870 bool wxDataViewCtrl::AssociateModel( wxDataViewModel 
*model 
) 
3881     if (!wxDataViewCtrlBase::AssociateModel( model 
)) 
3885     if (!gtk_check_version(2,6,0)) 
3887         bool fixed 
= (((GetWindowStyle() & wxDV_VARIABLE_LINE_HEIGHT
) == 0) || (model
->IsVirtualListModel())); 
3888         gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview
), fixed 
); 
3892     GtkWxTreeModel 
*gtk_model 
= wxgtk_tree_model_new(); 
3893     m_internal 
= new wxDataViewCtrlInternal( this, model
, gtk_model 
); 
3894     gtk_model
->internal 
= m_internal
; 
3896     m_notifier 
= new wxGtkDataViewModelNotifier( gtk_model
, model
, this ); 
3898     model
->AddNotifier( m_notifier 
); 
3900     gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview
), GTK_TREE_MODEL(gtk_model
) ); 
3902     // unref in wxDataViewCtrlInternal 
3903     // g_object_unref( gtk_model ); 
3908 bool wxDataViewCtrl::EnableDragSource( const wxDataFormat 
&format 
) 
3910     return m_internal
->EnableDragSource( format 
); 
3913 bool wxDataViewCtrl::AppendColumn( wxDataViewColumn 
*col 
) 
3915     if (!wxDataViewCtrlBase::AppendColumn(col
)) 
3918     m_cols
.Append( col 
); 
3921     if (!gtk_check_version(2,6,0)) 
3923         if (gtk_tree_view_column_get_sizing( GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()) ) != 
3924                GTK_TREE_VIEW_COLUMN_FIXED
) 
3925            gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview
), FALSE 
); 
3929     gtk_tree_view_append_column( GTK_TREE_VIEW(m_treeview
), 
3930                                  GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()) ); 
3935 bool wxDataViewCtrl::PrependColumn( wxDataViewColumn 
*col 
) 
3937     if (!wxDataViewCtrlBase::PrependColumn(col
)) 
3940     m_cols
.Insert( col 
); 
3943     if (!gtk_check_version(2,6,0)) 
3945         if (gtk_tree_view_column_get_sizing( GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()) ) != 
3946                GTK_TREE_VIEW_COLUMN_FIXED
) 
3947            gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview
), FALSE 
); 
3951     gtk_tree_view_insert_column( GTK_TREE_VIEW(m_treeview
), 
3952                                  GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()), 0 ); 
3957 bool wxDataViewCtrl::InsertColumn( unsigned int pos
, wxDataViewColumn 
*col 
) 
3959     if (!wxDataViewCtrlBase::InsertColumn(pos
,col
)) 
3962     m_cols
.Insert( pos
, col 
); 
3965     if (!gtk_check_version(2,6,0)) 
3967         if (gtk_tree_view_column_get_sizing( GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()) ) != 
3968                GTK_TREE_VIEW_COLUMN_FIXED
) 
3969            gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview
), FALSE 
); 
3973     gtk_tree_view_insert_column( GTK_TREE_VIEW(m_treeview
), 
3974                                  GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()), pos 
); 
3979 unsigned int wxDataViewCtrl::GetColumnCount() const 
3981     return m_cols
.GetCount(); 
3984 wxDataViewColumn
* wxDataViewCtrl::GetColumn( unsigned int pos 
) const 
3986     GtkTreeViewColumn 
*gtk_col 
= gtk_tree_view_get_column( GTK_TREE_VIEW(m_treeview
), pos 
); 
3990     wxDataViewColumnList::const_iterator iter
; 
3991     for (iter 
= m_cols
.begin(); iter 
!= m_cols
.end(); ++iter
) 
3993         wxDataViewColumn 
*col 
= *iter
; 
3994         if (GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()) == gtk_col
) 
4003 bool wxDataViewCtrl::DeleteColumn( wxDataViewColumn 
*column 
) 
4005     gtk_tree_view_remove_column( GTK_TREE_VIEW(m_treeview
), 
4006                                  GTK_TREE_VIEW_COLUMN(column
->GetGtkHandle()) ); 
4008     m_cols
.DeleteObject( column 
); 
4013 bool wxDataViewCtrl::ClearColumns() 
4015     wxDataViewColumnList::iterator iter
; 
4016     for (iter 
= m_cols
.begin(); iter 
!= m_cols
.end(); ++iter
) 
4018         wxDataViewColumn 
*col 
= *iter
; 
4019         gtk_tree_view_remove_column( GTK_TREE_VIEW(m_treeview
), 
4020                                      GTK_TREE_VIEW_COLUMN(col
->GetGtkHandle()) ); 
4028 int wxDataViewCtrl::GetColumnPosition( const wxDataViewColumn 
*column 
) const 
4030     GtkTreeViewColumn 
*gtk_column 
= GTK_TREE_VIEW_COLUMN(column
->GetConstGtkHandle()); 
4032     GList 
*list 
= gtk_tree_view_get_columns( GTK_TREE_VIEW(m_treeview
) ); 
4034     gint pos 
= g_list_index( list
, (gconstpointer
)  gtk_column 
); 
4036     g_list_free( list 
); 
4041 wxDataViewColumn 
*wxDataViewCtrl::GetSortingColumn() const 
4043     return m_internal
->GetDataViewSortColumn(); 
4046 void wxDataViewCtrl::Expand( const wxDataViewItem 
& item 
) 
4049     iter
.user_data 
= item
.GetID(); 
4050     GtkTreePath 
*path 
= m_internal
->get_path( &iter 
); 
4051     gtk_tree_view_expand_row( GTK_TREE_VIEW(m_treeview
), path
, false ); 
4052     gtk_tree_path_free( path 
); 
4055 void wxDataViewCtrl::Collapse( const wxDataViewItem 
& item 
) 
4058     iter
.user_data 
= item
.GetID(); 
4059     GtkTreePath 
*path 
= m_internal
->get_path( &iter 
); 
4060     gtk_tree_view_collapse_row( GTK_TREE_VIEW(m_treeview
), path 
); 
4061     gtk_tree_path_free( path 
); 
4064 bool wxDataViewCtrl::IsExpanded( const wxDataViewItem 
& item 
) const 
4067     iter
.user_data 
= item
.GetID(); 
4068     GtkTreePath 
*path 
= m_internal
->get_path( &iter 
); 
4069     bool res 
= gtk_tree_view_row_expanded( GTK_TREE_VIEW(m_treeview
), path 
); 
4070     gtk_tree_path_free( path 
); 
4075 wxDataViewItem 
wxDataViewCtrl::GetSelection() const 
4077     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4079     if (m_windowStyle 
& wxDV_MULTIPLE
) 
4081         // Report the first one 
4082         GtkTreeModel 
*model
; 
4083         GList 
*list 
= gtk_tree_selection_get_selected_rows( selection
, &model 
); 
4087             GtkTreePath 
*path 
= (GtkTreePath
*) list
->data
; 
4089             m_internal
->get_iter( &iter
, path 
); 
4092             g_list_foreach( list
, (GFunc
) gtk_tree_path_free
, NULL 
); 
4093             g_list_free( list 
); 
4095             return wxDataViewItem( (void*) iter
.user_data 
); 
4101         if (gtk_tree_selection_get_selected( selection
, NULL
, &iter 
)) 
4103             wxDataViewItem 
item( (void*) iter
.user_data 
); 
4108     return wxDataViewItem(0); 
4111 int wxDataViewCtrl::GetSelections( wxDataViewItemArray 
& sel 
) const 
4115     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4116     if (HasFlag(wxDV_MULTIPLE
)) 
4118         GtkTreeModel 
*model
; 
4119         GList 
*list 
= gtk_tree_selection_get_selected_rows( selection
, &model 
); 
4124             GtkTreePath 
*path 
= (GtkTreePath
*) list
->data
; 
4127             m_internal
->get_iter( &iter
, path 
); 
4129             sel
.Add( wxDataViewItem( (void*) iter
.user_data 
) ); 
4131             list 
= g_list_next( list 
); 
4136         g_list_foreach( list
, (GFunc
) gtk_tree_path_free
, NULL 
); 
4137         g_list_free( list 
); 
4143         GtkTreeModel 
*model
; 
4145         gboolean has_selection 
= gtk_tree_selection_get_selected( selection
, &model
, &iter 
); 
4148             sel
.Add( wxDataViewItem( (void*) iter
.user_data
) ); 
4156 void wxDataViewCtrl::SetSelections( const wxDataViewItemArray 
& sel 
) 
4158     GtkDisableSelectionEvents(); 
4160     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4162     gtk_tree_selection_unselect_all( selection 
); 
4164     wxDataViewItem last_parent
; 
4167     for (i 
= 0; i 
< sel
.GetCount(); i
++) 
4169         wxDataViewItem item 
= sel
[i
]; 
4170         wxDataViewItem parent 
= GetModel()->GetParent( item 
); 
4173             if (parent 
!= last_parent
) 
4174                 ExpandAncestors(item
); 
4176         last_parent 
= parent
; 
4179         iter
.stamp 
= m_internal
->GetGtkModel()->stamp
; 
4180         iter
.user_data 
= (gpointer
) item
.GetID(); 
4181         gtk_tree_selection_select_iter( selection
, &iter 
); 
4184     GtkEnableSelectionEvents(); 
4187 void wxDataViewCtrl::Select( const wxDataViewItem 
& item 
) 
4189     ExpandAncestors(item
); 
4191     GtkDisableSelectionEvents(); 
4193     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4196     iter
.stamp 
= m_internal
->GetGtkModel()->stamp
; 
4197     iter
.user_data 
= (gpointer
) item
.GetID(); 
4198     gtk_tree_selection_select_iter( selection
, &iter 
); 
4200     GtkEnableSelectionEvents(); 
4203 void wxDataViewCtrl::Unselect( const wxDataViewItem 
& item 
) 
4205     GtkDisableSelectionEvents(); 
4207     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4210     iter
.stamp 
= m_internal
->GetGtkModel()->stamp
; 
4211     iter
.user_data 
= (gpointer
) item
.GetID(); 
4212     gtk_tree_selection_unselect_iter( selection
, &iter 
); 
4214     GtkEnableSelectionEvents(); 
4217 bool wxDataViewCtrl::IsSelected( const wxDataViewItem 
& item 
) const 
4219     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4222     iter
.stamp 
= m_internal
->GetGtkModel()->stamp
; 
4223     iter
.user_data 
= (gpointer
) item
.GetID(); 
4225     return gtk_tree_selection_iter_is_selected( selection
, &iter 
); 
4228 void wxDataViewCtrl::SelectAll() 
4230     GtkDisableSelectionEvents(); 
4232     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4234     gtk_tree_selection_select_all( selection 
); 
4236     GtkEnableSelectionEvents(); 
4239 void wxDataViewCtrl::UnselectAll() 
4241     GtkDisableSelectionEvents(); 
4243     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4245     gtk_tree_selection_unselect_all( selection 
); 
4247     GtkEnableSelectionEvents(); 
4250 void wxDataViewCtrl::EnsureVisible(const wxDataViewItem
& item
, 
4251                                    const wxDataViewColumn 
*WXUNUSED(column
)) 
4253     ExpandAncestors(item
); 
4256     iter
.user_data 
= (gpointer
) item
.GetID(); 
4257     GtkTreePath 
*path 
= m_internal
->get_path( &iter 
); 
4258     gtk_tree_view_scroll_to_cell( GTK_TREE_VIEW(m_treeview
), path
, NULL
, false, 0.0, 0.0 ); 
4259     gtk_tree_path_free( path 
); 
4262 void wxDataViewCtrl::HitTest(const wxPoint
& WXUNUSED(point
), 
4263                              wxDataViewItem
& item
, 
4264                              wxDataViewColumn 
*& column
) const 
4266     item 
= wxDataViewItem(0); 
4271 wxDataViewCtrl::GetItemRect(const wxDataViewItem
& WXUNUSED(item
), 
4272                             const wxDataViewColumn 
*WXUNUSED(column
)) const 
4277 void wxDataViewCtrl::DoSetExpanderColumn() 
4279     gtk_tree_view_set_expander_column( GTK_TREE_VIEW(m_treeview
), 
4280         GTK_TREE_VIEW_COLUMN( GetExpanderColumn()->GetGtkHandle() ) ); 
4283 void wxDataViewCtrl::DoSetIndent() 
4287 void wxDataViewCtrl::GtkDisableSelectionEvents() 
4289     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4290     g_signal_handlers_disconnect_by_func( selection
, 
4291                             (gpointer
) (wxdataview_selection_changed_callback
), this); 
4294 void wxDataViewCtrl::GtkEnableSelectionEvents() 
4296     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
4297     g_signal_connect_after (selection
, "changed", 
4298                             G_CALLBACK (wxdataview_selection_changed_callback
), this); 
4303 wxDataViewCtrl::GetClassDefaultAttributes(wxWindowVariant 
WXUNUSED(variant
)) 
4305     return GetDefaultAttributesFromGTKWidget(gtk_tree_view_new
); 
4310     // !wxUSE_GENERICDATAVIEWCTRL 
4313     // wxUSE_DATAVIEWCTRL