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/stockitem.h" 
  26 #include "wx/calctrl.h" 
  27 #include "wx/popupwin.h" 
  30 #include "wx/listimpl.cpp" 
  33 #include "wx/gtk/private.h" 
  34 #include "wx/gtk/win_gtk.h" 
  36 #include <gobject/gvaluecollector.h> 
  37 #include <gtk/gtktreemodel.h> 
  38 #include <gtk/gtktreesortable.h> 
  39 #include <gtk/gtktreednd.h> 
  41 #include <gdk/gdkkeysyms.h> 
  43 //----------------------------------------------------------------------------- 
  44 //----------------------------------------------------------------------------- 
  46 class wxDataViewCtrlInternal
; 
  48 wxDataViewCtrlInternal 
*g_internal 
= NULL
; 
  50 class wxGtkTreeModelNode
; 
  53 typedef struct _GtkWxTreeModel       GtkWxTreeModel
; 
  56 //----------------------------------------------------------------------------- 
  57 // wxDataViewCtrlInternal 
  58 //----------------------------------------------------------------------------- 
  60 WX_DECLARE_LIST(wxDataViewItem
, ItemList
); 
  61 WX_DEFINE_LIST(ItemList
); 
  63 class wxDataViewCtrlInternal
 
  66     wxDataViewCtrlInternal( wxDataViewCtrl 
*owner
, wxDataViewModel 
*wx_model
, GtkWxTreeModel 
*owner 
); 
  67     ~wxDataViewCtrlInternal(); 
  69     gboolean 
get_iter( GtkTreeIter 
*iter
, GtkTreePath 
*path 
); 
  70     GtkTreePath 
*get_path( GtkTreeIter 
*iter
); 
  71     gboolean 
iter_next( GtkTreeIter 
*iter 
); 
  72     gboolean 
iter_children( GtkTreeIter 
*iter
, GtkTreeIter 
*parent
); 
  73     gboolean 
iter_has_child( GtkTreeIter 
*iter 
); 
  74     gint 
iter_n_children( GtkTreeIter 
*iter 
); 
  75     gboolean 
iter_nth_child( GtkTreeIter 
*iter
, GtkTreeIter 
*parent
, gint n 
); 
  76     gboolean 
iter_parent( GtkTreeIter 
*iter
, GtkTreeIter 
*child 
); 
  78     wxDataViewModel
* GetDataViewModel() { return m_wx_model
; } 
  79     wxDataViewCtrl
* GetOwner()          { return m_owner
; } 
  80     GtkWxTreeModel
* GetGtkModel()       { return m_gtk_model
; } 
  82     bool ItemAdded( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
); 
  83     bool ItemDeleted( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
); 
  84     bool ItemChanged( const wxDataViewItem 
&item 
); 
  85     bool ValueChanged( const wxDataViewItem 
&item
, unsigned int col 
); 
  89     void SetSortOrder( GtkSortType sort_order 
) { m_sort_order 
= sort_order
; } 
  90     GtkSortType 
GetSortOrder()                  { return m_sort_order
; } 
  92     void SetSortColumn( int column 
)            { m_sort_column 
= column
; } 
  93     int GetSortColumn()                         { return m_sort_column
; } 
  95     bool IsSorted()                             { return (m_sort_column 
>= 0); } 
 100     wxGtkTreeModelNode 
*FindNode( const wxDataViewItem 
&item 
); 
 101     wxGtkTreeModelNode 
*FindNode( GtkTreeIter 
*iter 
); 
 102     wxGtkTreeModelNode 
*FindParentNode( const wxDataViewItem 
&item 
); 
 103     wxGtkTreeModelNode 
*FindParentNode( GtkTreeIter 
*iter 
); 
 104     void BuildBranch( wxGtkTreeModelNode 
*branch 
); 
 107     wxGtkTreeModelNode   
*m_root
; 
 108     wxDataViewModel      
*m_wx_model
; 
 109     GtkWxTreeModel       
*m_gtk_model
; 
 110     wxDataViewCtrl       
*m_owner
; 
 111     GtkSortType           m_sort_order
; 
 116 //----------------------------------------------------------------------------- 
 117 // wxGtkTreeModelNode 
 118 //----------------------------------------------------------------------------- 
 120 int LINKAGEMODE 
wxGtkTreeModelChildCmp( void** id1
, void** id2 
) 
 122     int ret 
= g_internal
->GetDataViewModel()->Compare( *id1
, *id2
,  
 123         g_internal
->GetSortColumn(), (g_internal
->GetSortOrder() == GTK_SORT_ASCENDING
) ); 
 128 WX_DEFINE_ARRAY_PTR( wxGtkTreeModelNode
*, wxGtkTreeModelNodes 
); 
 129 WX_DEFINE_ARRAY_PTR( void*, wxGtkTreeModelChildren 
); 
 131 class wxGtkTreeModelNode
 
 134     wxGtkTreeModelNode( wxGtkTreeModelNode
* parent
, const wxDataViewItem 
&item
, 
 135       wxDataViewCtrlInternal 
*internal 
) 
 139         m_internal 
= internal
; 
 142     ~wxGtkTreeModelNode() 
 144         size_t count 
= m_children
.GetCount(); 
 146         for (i 
= 0; i 
< count
; i
++) 
 148             wxGtkTreeModelNode 
*child 
= m_nodes
.Item( i 
); 
 153     unsigned int AddNode( wxGtkTreeModelNode
* child 
)  
 155             m_nodes
.Add( child 
); 
 157             void *id 
= child
->GetItem().GetID(); 
 159             m_children
.Add( id 
); 
 161             if (m_internal
->IsSorted() || m_internal
->GetDataViewModel()->HasDefaultCompare()) 
 163                 g_internal 
= m_internal
; 
 164                 m_children
.Sort( &wxGtkTreeModelChildCmp 
); 
 165                 return m_children
.Index( id 
); 
 168             return m_children
.GetCount()-1; 
 171     unsigned int AddLeave( void* id 
) 
 173             m_children
.Add( id 
); 
 175             if (m_internal
->IsSorted() || m_internal
->GetDataViewModel()->HasDefaultCompare()) 
 177                 g_internal 
= m_internal
; 
 178                 m_children
.Sort( &wxGtkTreeModelChildCmp 
); 
 179                 return m_children
.Index( id 
); 
 182             return m_children
.GetCount()-1; 
 185     void DeleteChild( void* id 
) 
 187             m_children
.Remove( id 
); 
 189             unsigned int count 
= m_nodes
.GetCount(); 
 191             for (pos 
= 0; pos 
< count
; pos
++) 
 193                 wxGtkTreeModelNode 
*node 
= m_nodes
.Item( pos 
); 
 194                 if (node
->GetItem().GetID() == id
) 
 196                     m_nodes
.RemoveAt( pos 
); 
 204     wxGtkTreeModelNode
* GetParent()  
 206     wxGtkTreeModelNodes 
&GetNodes()  
 208     wxGtkTreeModelChildren 
&GetChildren()  
 209         { return m_children
; } 
 211     unsigned int GetChildCount() { return m_children
.GetCount(); } 
 212     unsigned int GetNodesCount() { return m_nodes
.GetCount(); } 
 214     wxDataViewItem 
&GetItem() { return m_item
; } 
 215     wxDataViewCtrlInternal 
*GetInternal() { return m_internal
; } 
 220     wxGtkTreeModelNode         
*m_parent
; 
 221     wxGtkTreeModelNodes         m_nodes
; 
 222     wxGtkTreeModelChildren      m_children
; 
 223     wxDataViewItem              m_item
;  
 224     wxDataViewCtrlInternal     
*m_internal
; 
 228 //----------------------------------------------------------------------------- 
 230 //----------------------------------------------------------------------------- 
 232 extern bool   g_blockEventsOnDrag
; 
 234 //----------------------------------------------------------------------------- 
 235 // define new GTK+ class wxGtkTreeModel 
 236 //----------------------------------------------------------------------------- 
 240 #define GTK_TYPE_WX_TREE_MODEL               (gtk_wx_tree_model_get_type ()) 
 241 #define GTK_WX_TREE_MODEL(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModel)) 
 242 #define GTK_WX_TREE_MODEL_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModelClass)) 
 243 #define GTK_IS_WX_TREE_MODEL(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_TREE_MODEL)) 
 244 #define GTK_IS_WX_TREE_MODEL_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_TREE_MODEL)) 
 245 #define GTK_WX_TREE_MODEL_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModelClass)) 
 247 GType         
gtk_wx_tree_model_get_type         (void); 
 249 typedef struct _GtkWxTreeModelClass  GtkWxTreeModelClass
; 
 251 struct _GtkWxTreeModel
 
 257   wxDataViewCtrlInternal 
*internal
; 
 260 struct _GtkWxTreeModelClass
 
 262   GObjectClass list_parent_class
; 
 265 static GtkWxTreeModel 
*wxgtk_tree_model_new          (void); 
 266 static void         wxgtk_tree_model_init            (GtkWxTreeModel       
*tree_model
); 
 267 static void         wxgtk_tree_model_class_init      (GtkWxTreeModelClass  
*klass
); 
 268 static void         wxgtk_tree_model_tree_model_init (GtkTreeModelIface    
*iface
); 
 269 static void         wxgtk_tree_model_sortable_init   (GtkTreeSortableIface 
*iface
); 
 270 static void         wxgtk_tree_model_finalize        (GObject           
*object
); 
 271 static GtkTreeModelFlags 
wxgtk_tree_model_get_flags  (GtkTreeModel      
*tree_model
); 
 272 static gint         
wxgtk_tree_model_get_n_columns   (GtkTreeModel      
*tree_model
); 
 273 static GType        
wxgtk_tree_model_get_column_type (GtkTreeModel      
*tree_model
, 
 275 static gboolean     
wxgtk_tree_model_get_iter        (GtkTreeModel      
*tree_model
, 
 278 static GtkTreePath 
*wxgtk_tree_model_get_path        (GtkTreeModel      
*tree_model
, 
 280 static void         wxgtk_tree_model_get_value       (GtkTreeModel      
*tree_model
, 
 284 static gboolean     
wxgtk_tree_model_iter_next       (GtkTreeModel      
*tree_model
, 
 286 static gboolean     
wxgtk_tree_model_iter_children   (GtkTreeModel      
*tree_model
, 
 288                                                       GtkTreeIter       
*parent
); 
 289 static gboolean     
wxgtk_tree_model_iter_has_child  (GtkTreeModel      
*tree_model
, 
 291 static gint         
wxgtk_tree_model_iter_n_children (GtkTreeModel      
*tree_model
, 
 293 static gboolean     
wxgtk_tree_model_iter_nth_child  (GtkTreeModel      
*tree_model
, 
 297 static gboolean     
wxgtk_tree_model_iter_parent     (GtkTreeModel      
*tree_model
, 
 302 static gboolean 
wxgtk_tree_model_get_sort_column_id    (GtkTreeSortable       
*sortable
, 
 303                                                       gint                     
*sort_column_id
, 
 305 static void     wxgtk_tree_model_set_sort_column_id    (GtkTreeSortable       
*sortable
, 
 308 static void     wxgtk_tree_model_set_sort_func         (GtkTreeSortable       
*sortable
, 
 310                                                       GtkTreeIterCompareFunc    func
, 
 312                                                       GtkDestroyNotify          destroy
); 
 313 static void     wxgtk_tree_model_set_default_sort_func (GtkTreeSortable       
*sortable
, 
 314                                                       GtkTreeIterCompareFunc    func
, 
 316                                                       GtkDestroyNotify          destroy
); 
 317 static gboolean 
wxgtk_tree_model_has_default_sort_func (GtkTreeSortable       
*sortable
); 
 321 static GObjectClass 
*list_parent_class 
= NULL
; 
 324 gtk_wx_tree_model_get_type (void) 
 326     static GType tree_model_type 
= 0; 
 328     if (!tree_model_type
) 
 330         const GTypeInfo tree_model_info 
= 
 332             sizeof (GtkWxTreeModelClass
), 
 333             NULL
,   /* base_init */ 
 334             NULL
,   /* base_finalize */ 
 335             (GClassInitFunc
) wxgtk_tree_model_class_init
, 
 336             NULL
,   /* class_finalize */ 
 337             NULL
,   /* class_data */ 
 338             sizeof (GtkWxTreeModel
), 
 340             (GInstanceInitFunc
) wxgtk_tree_model_init
, 
 343         static const GInterfaceInfo tree_model_iface_info 
= 
 345             (GInterfaceInitFunc
) wxgtk_tree_model_tree_model_init
, 
 350         static const GInterfaceInfo sortable_iface_info 
= 
 352             (GInterfaceInitFunc
) wxgtk_tree_model_sortable_init
, 
 357         tree_model_type 
= g_type_register_static (G_TYPE_OBJECT
, "GtkWxTreeModel", 
 358                                                 &tree_model_info
, (GTypeFlags
)0 ); 
 360         g_type_add_interface_static (tree_model_type
, 
 362                                      &tree_model_iface_info
); 
 363         g_type_add_interface_static (tree_model_type
, 
 364                                      GTK_TYPE_TREE_SORTABLE
, 
 365                                      &sortable_iface_info
); 
 368     return tree_model_type
; 
 371 static GtkWxTreeModel 
* 
 372 wxgtk_tree_model_new(void) 
 374     GtkWxTreeModel 
*retval 
= (GtkWxTreeModel 
*) g_object_new (GTK_TYPE_WX_TREE_MODEL
, NULL
); 
 379 wxgtk_tree_model_class_init (GtkWxTreeModelClass 
*klass
) 
 381     list_parent_class 
= (GObjectClass
*) g_type_class_peek_parent (klass
); 
 382     GObjectClass 
*object_class 
= (GObjectClass
*) klass
; 
 383     object_class
->finalize 
= wxgtk_tree_model_finalize
; 
 387 wxgtk_tree_model_tree_model_init (GtkTreeModelIface 
*iface
) 
 389     iface
->get_flags 
= wxgtk_tree_model_get_flags
; 
 390     iface
->get_n_columns 
= wxgtk_tree_model_get_n_columns
; 
 391     iface
->get_column_type 
= wxgtk_tree_model_get_column_type
; 
 392     iface
->get_iter 
= wxgtk_tree_model_get_iter
; 
 393     iface
->get_path 
= wxgtk_tree_model_get_path
; 
 394     iface
->get_value 
= wxgtk_tree_model_get_value
; 
 395     iface
->iter_next 
= wxgtk_tree_model_iter_next
; 
 396     iface
->iter_children 
= wxgtk_tree_model_iter_children
; 
 397     iface
->iter_has_child 
= wxgtk_tree_model_iter_has_child
; 
 398     iface
->iter_n_children 
= wxgtk_tree_model_iter_n_children
; 
 399     iface
->iter_nth_child 
= wxgtk_tree_model_iter_nth_child
; 
 400     iface
->iter_parent 
= wxgtk_tree_model_iter_parent
; 
 404 wxgtk_tree_model_sortable_init (GtkTreeSortableIface 
*iface
) 
 406     iface
->get_sort_column_id 
= wxgtk_tree_model_get_sort_column_id
; 
 407     iface
->set_sort_column_id 
= wxgtk_tree_model_set_sort_column_id
; 
 408     iface
->set_sort_func 
= wxgtk_tree_model_set_sort_func
; 
 409     iface
->set_default_sort_func 
= wxgtk_tree_model_set_default_sort_func
; 
 410     iface
->has_default_sort_func 
= wxgtk_tree_model_has_default_sort_func
; 
 414 wxgtk_tree_model_init (GtkWxTreeModel 
*tree_model
) 
 416     tree_model
->internal 
= NULL
; 
 417     tree_model
->stamp 
= g_random_int(); 
 421 wxgtk_tree_model_finalize (GObject 
*object
) 
 424     (* list_parent_class
->finalize
) (object
); 
 429 //----------------------------------------------------------------------------- 
 430 // implement callbacks from wxGtkTreeModel class by letting 
 431 // them call the methods of wxWidgets' wxDataViewModel 
 432 //----------------------------------------------------------------------------- 
 434 static GtkTreeModelFlags
 
 435 wxgtk_tree_model_get_flags (GtkTreeModel 
*tree_model
) 
 437     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (tree_model
), (GtkTreeModelFlags
)0 ); 
 439     return GTK_TREE_MODEL_ITERS_PERSIST
; 
 443 wxgtk_tree_model_get_n_columns (GtkTreeModel 
*tree_model
) 
 445     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 446     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), 0); 
 448     return wxtree_model
->internal
->GetDataViewModel()->GetColumnCount(); 
 452 wxgtk_tree_model_get_column_type (GtkTreeModel 
*tree_model
, 
 455     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 456     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), G_TYPE_INVALID
); 
 458     GType gtype 
= G_TYPE_INVALID
; 
 460     wxString wxtype 
= wxtree_model
->internal
->GetDataViewModel()->GetColumnType( (unsigned int) index 
); 
 462     if (wxtype 
== wxT("string")) 
 463         gtype 
= G_TYPE_STRING
; 
 466         wxFAIL_MSG( _T("non-string columns not supported yet") ); 
 473 wxgtk_tree_model_get_iter (GtkTreeModel 
*tree_model
, 
 477     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 478     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 479     g_return_val_if_fail (gtk_tree_path_get_depth (path
) > 0, FALSE
); 
 481     return wxtree_model
->internal
->get_iter( iter
, path 
); 
 485 wxgtk_tree_model_get_path (GtkTreeModel 
*tree_model
, 
 488     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 489     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), NULL
); 
 490     g_return_val_if_fail (iter
->stamp 
== GTK_WX_TREE_MODEL (wxtree_model
)->stamp
, NULL
); 
 492     return wxtree_model
->internal
->get_path( iter 
); 
 496 wxgtk_tree_model_get_value (GtkTreeModel 
*tree_model
, 
 501     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 502     g_return_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
) ); 
 504     wxDataViewModel 
*model 
= wxtree_model
->internal
->GetDataViewModel(); 
 505     wxString mtype 
= model
->GetColumnType( (unsigned int) column 
); 
 506     if (mtype 
== wxT("string")) 
 509         g_value_init( value
, G_TYPE_STRING 
); 
 510         wxDataViewItem 
item( (void*) iter
->user_data 
); 
 511         model
->GetValue( variant
, item
, (unsigned int) column 
); 
 513         g_value_set_string( value
, variant
.GetString().utf8_str() ); 
 517         wxFAIL_MSG( _T("non-string columns not supported yet") ); 
 522 wxgtk_tree_model_iter_next (GtkTreeModel  
*tree_model
, 
 525     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 526     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 527     g_return_val_if_fail (wxtree_model
->stamp 
== iter
->stamp
, FALSE
); 
 529     return wxtree_model
->internal
->iter_next( iter 
); 
 533 wxgtk_tree_model_iter_children (GtkTreeModel 
*tree_model
, 
 537     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 538     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 539     g_return_val_if_fail (wxtree_model
->stamp 
== parent
->stamp
, FALSE
); 
 541     return wxtree_model
->internal
->iter_children( iter
, parent 
); 
 545 wxgtk_tree_model_iter_has_child (GtkTreeModel 
*tree_model
, 
 548     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 549     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 550     g_return_val_if_fail (wxtree_model
->stamp 
== iter
->stamp
, FALSE
); 
 552     return wxtree_model
->internal
->iter_has_child( iter 
); 
 556 wxgtk_tree_model_iter_n_children (GtkTreeModel 
*tree_model
, 
 559     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 560     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 561     g_return_val_if_fail (wxtree_model
->stamp 
== iter
->stamp
, 0); 
 563     return wxtree_model
->internal
->iter_n_children( iter 
); 
 567 wxgtk_tree_model_iter_nth_child (GtkTreeModel 
*tree_model
, 
 572     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 573     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 575     return wxtree_model
->internal
->iter_nth_child( iter
, parent
, n 
); 
 579 wxgtk_tree_model_iter_parent (GtkTreeModel 
*tree_model
, 
 583     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 584     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 585     g_return_val_if_fail (wxtree_model
->stamp 
== child
->stamp
, FALSE
); 
 587     return wxtree_model
->internal
->iter_parent( iter
, child 
); 
 591 gboolean 
wxgtk_tree_model_get_sort_column_id    (GtkTreeSortable        
*sortable
, 
 592                                                       gint                     
*sort_column_id
, 
 595     GtkWxTreeModel 
*tree_model 
= (GtkWxTreeModel 
*) sortable
; 
 597     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (sortable
), FALSE
); 
 599     if (!tree_model
->internal
->IsSorted()) 
 602             *sort_column_id 
= -1; 
 609         *sort_column_id 
= tree_model
->internal
->GetSortColumn(); 
 612         *order 
= tree_model
->internal
->GetSortOrder(); 
 617 void     wxgtk_tree_model_set_sort_column_id  (GtkTreeSortable        
*sortable
, 
 621     GtkWxTreeModel 
*tree_model 
= (GtkWxTreeModel 
*) sortable
; 
 622     g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable
) ); 
 624     if ((sort_column_id 
== (gint
) tree_model
->internal
->GetSortColumn()) && 
 625         (order 
== tree_model
->internal
->GetSortOrder())) 
 628     tree_model
->internal
->SetSortColumn( sort_column_id 
); 
 630     tree_model
->internal
->SetSortOrder( order 
); 
 632     gtk_tree_sortable_sort_column_changed (sortable
); 
 634     tree_model
->internal
->GetDataViewModel()->Resort(); 
 636     wxDataViewCtrl 
*dv 
= tree_model
->internal
->GetOwner();     
 637     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED
, dv
->GetId() ); 
 638     // TODO event.SetDataViewColumn( column ); 
 639     event
.SetModel( dv
->GetModel() ); 
 640     dv
->GetEventHandler()->ProcessEvent( event 
); 
 643 void     wxgtk_tree_model_set_sort_func         (GtkTreeSortable        
*sortable
, 
 645                                                       GtkTreeIterCompareFunc    func
, 
 647                                                       GtkDestroyNotify          destroy
) 
 649     g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable
) ); 
 650     g_return_if_fail (func 
!= NULL
); 
 653 void     wxgtk_tree_model_set_default_sort_func (GtkTreeSortable        
*sortable
, 
 654                                                       GtkTreeIterCompareFunc    func
, 
 656                                                       GtkDestroyNotify          destroy
) 
 658     g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable
) ); 
 659     g_return_if_fail (func 
!= NULL
); 
 661     wxPrintf( "wxgtk_tree_model_set_default_sort_func\n" ); 
 664 gboolean 
wxgtk_tree_model_has_default_sort_func (GtkTreeSortable        
*sortable
) 
 669 //----------------------------------------------------------------------------- 
 670 // define new GTK+ class wxGtkRendererRenderer 
 671 //----------------------------------------------------------------------------- 
 675 #define GTK_TYPE_WX_CELL_RENDERER               (gtk_wx_cell_renderer_get_type ()) 
 676 #define GTK_WX_CELL_RENDERER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRenderer)) 
 677 #define GTK_WX_CELL_RENDERER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRendererClass)) 
 678 #define GTK_IS_WX_CELL_RENDERER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_CELL_RENDERER)) 
 679 #define GTK_IS_WX_CELL_RENDERER_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_CELL_RENDERER)) 
 680 #define GTK_WX_CELL_RENDERER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRendererClass)) 
 682 GType            
gtk_wx_cell_renderer_get_type (void); 
 684 typedef struct _GtkWxCellRenderer GtkWxCellRenderer
; 
 685 typedef struct _GtkWxCellRendererClass GtkWxCellRendererClass
; 
 687 struct _GtkWxCellRenderer
 
 689   GtkCellRenderer parent
; 
 692   wxDataViewCustomRenderer 
*cell
; 
 696 struct _GtkWxCellRendererClass
 
 698   GtkCellRendererClass cell_parent_class
; 
 702 static GtkCellRenderer 
*gtk_wx_cell_renderer_new   (void); 
 703 static void gtk_wx_cell_renderer_init ( 
 704                         GtkWxCellRenderer      
*cell 
); 
 705 static void gtk_wx_cell_renderer_class_init( 
 706                         GtkWxCellRendererClass 
*klass 
); 
 707 static void gtk_wx_cell_renderer_finalize ( 
 709 static void gtk_wx_cell_renderer_get_size ( 
 710                         GtkCellRenderer         
*cell
, 
 712                         GdkRectangle            
*rectangle
, 
 717 static void gtk_wx_cell_renderer_render ( 
 718                         GtkCellRenderer         
*cell
, 
 721                         GdkRectangle            
*background_area
, 
 722                         GdkRectangle            
*cell_area
, 
 723                         GdkRectangle            
*expose_area
, 
 724                         GtkCellRendererState     flags 
); 
 725 static gboolean 
gtk_wx_cell_renderer_activate( 
 726                         GtkCellRenderer         
*cell
, 
 730                         GdkRectangle            
*background_area
, 
 731                         GdkRectangle            
*cell_area
, 
 732                         GtkCellRendererState     flags 
); 
 733 static GtkCellEditable 
*gtk_wx_cell_renderer_start_editing( 
 734                         GtkCellRenderer         
*cell
, 
 738                         GdkRectangle            
*background_area
, 
 739                         GdkRectangle            
*cell_area
, 
 740                         GtkCellRendererState     flags 
); 
 743 static GObjectClass 
*cell_parent_class 
= NULL
; 
 748 gtk_wx_cell_renderer_get_type (void) 
 750     static GType cell_wx_type 
= 0; 
 754         const GTypeInfo cell_wx_info 
= 
 756             sizeof (GtkWxCellRendererClass
), 
 757             NULL
, /* base_init */ 
 758             NULL
, /* base_finalize */ 
 759             (GClassInitFunc
) gtk_wx_cell_renderer_class_init
, 
 760             NULL
, /* class_finalize */ 
 761             NULL
, /* class_data */ 
 762             sizeof (GtkWxCellRenderer
), 
 764             (GInstanceInitFunc
) gtk_wx_cell_renderer_init
, 
 767         cell_wx_type 
= g_type_register_static( GTK_TYPE_CELL_RENDERER
, 
 768             "GtkWxCellRenderer", &cell_wx_info
, (GTypeFlags
)0 ); 
 775 gtk_wx_cell_renderer_init (GtkWxCellRenderer 
*cell
) 
 778     cell
->last_click 
= 0; 
 782 gtk_wx_cell_renderer_class_init (GtkWxCellRendererClass 
*klass
) 
 784     GObjectClass 
*object_class 
= G_OBJECT_CLASS (klass
); 
 785     GtkCellRendererClass 
*cell_class 
= GTK_CELL_RENDERER_CLASS (klass
); 
 787     cell_parent_class 
= (GObjectClass
*) g_type_class_peek_parent (klass
); 
 789     object_class
->finalize 
= gtk_wx_cell_renderer_finalize
; 
 791     cell_class
->get_size 
= gtk_wx_cell_renderer_get_size
; 
 792     cell_class
->render 
= gtk_wx_cell_renderer_render
; 
 793     cell_class
->activate 
= gtk_wx_cell_renderer_activate
; 
 794     cell_class
->start_editing 
= gtk_wx_cell_renderer_start_editing
; 
 798 gtk_wx_cell_renderer_finalize (GObject 
*object
) 
 801     (* G_OBJECT_CLASS (cell_parent_class
)->finalize
) (object
); 
 805 gtk_wx_cell_renderer_new (void) 
 807     return (GtkCellRenderer
*) g_object_new (GTK_TYPE_WX_CELL_RENDERER
, NULL
); 
 812 static GtkCellEditable 
*gtk_wx_cell_renderer_start_editing( 
 813                         GtkCellRenderer         
*renderer
, 
 817                         GdkRectangle            
*background_area
, 
 818                         GdkRectangle            
*cell_area
, 
 819                         GtkCellRendererState     flags 
) 
 821     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
 822     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
 823     if (!cell
->HasEditorCtrl()) 
 827     gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
, 
 833     rect
.x 
+= cell_area
->x
; 
 834     rect
.y 
+= cell_area
->y
; 
 835 //    rect.width  -= renderer->xpad * 2; 
 836 //    rect.height -= renderer->ypad * 2; 
 838 //    wxRect renderrect( rect.x, rect.y, rect.width, rect.height ); 
 839     wxRect 
renderrect( cell_area
->x
, cell_area
->y
, cell_area
->width
, cell_area
->height 
); 
 841     GtkTreePath 
*treepath 
= gtk_tree_path_new_from_string( path 
); 
 843     cell
->GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter
, treepath 
); 
 844     wxDataViewItem 
item( (void*) iter
.user_data 
); 
 845     gtk_tree_path_free( treepath 
); 
 847     cell
->StartEditing( item
, renderrect 
); 
 853 gtk_wx_cell_renderer_get_size (GtkCellRenderer 
*renderer
, 
 855                                GdkRectangle    
*cell_area
, 
 861     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
 862     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
 864     wxSize size 
= cell
->GetSize(); 
 866     gint calc_width  
= (gint
) renderer
->xpad 
* 2 + size
.x
; 
 867     gint calc_height 
= (gint
) renderer
->ypad 
* 2 + size
.y
; 
 874     if (cell_area 
&& size
.x 
> 0 && size
.y 
> 0) 
 878             *x_offset 
= (gint
)((renderer
->xalign 
* 
 879                                (cell_area
->width 
- calc_width 
- 2 * renderer
->xpad
))); 
 880             *x_offset 
= MAX (*x_offset
, 0) + renderer
->xpad
; 
 884             *y_offset 
= (gint
)((renderer
->yalign 
* 
 885                                (cell_area
->height 
- calc_height 
- 2 * renderer
->ypad
))); 
 886             *y_offset 
= MAX (*y_offset
, 0) + renderer
->ypad
; 
 894         *height 
= calc_height
; 
 898 gtk_wx_cell_renderer_render (GtkCellRenderer      
*renderer
, 
 901                              GdkRectangle         
*background_area
, 
 902                              GdkRectangle         
*cell_area
, 
 903                              GdkRectangle         
*expose_area
, 
 904                              GtkCellRendererState  flags
) 
 907     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
 908     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
 911     gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
, 
 917     rect
.x 
+= cell_area
->x
; 
 918     rect
.y 
+= cell_area
->y
; 
 919     rect
.width  
-= renderer
->xpad 
* 2; 
 920     rect
.height 
-= renderer
->ypad 
* 2; 
 923     if (gdk_rectangle_intersect (expose_area
, &rect
, &dummy
)) 
 925         wxRect 
renderrect( rect
.x
, rect
.y
, rect
.width
, rect
.height 
); 
 926         wxWindowDC
* dc 
= (wxWindowDC
*) cell
->GetDC(); 
 927         if (dc
->m_window 
== NULL
) 
 929             dc
->m_window 
= window
; 
 934         if (flags 
& GTK_CELL_RENDERER_SELECTED
) 
 935             state 
|= wxDATAVIEW_CELL_SELECTED
; 
 936         if (flags 
& GTK_CELL_RENDERER_PRELIT
) 
 937             state 
|= wxDATAVIEW_CELL_PRELIT
; 
 938         if (flags 
& GTK_CELL_RENDERER_INSENSITIVE
) 
 939             state 
|= wxDATAVIEW_CELL_INSENSITIVE
; 
 940         if (flags 
& GTK_CELL_RENDERER_INSENSITIVE
) 
 941             state 
|= wxDATAVIEW_CELL_INSENSITIVE
; 
 942         if (flags 
& GTK_CELL_RENDERER_FOCUSED
) 
 943             state 
|= wxDATAVIEW_CELL_FOCUSED
; 
 944         cell
->Render( renderrect
, dc
, state 
); 
 949 gtk_wx_cell_renderer_activate( 
 950                         GtkCellRenderer         
*renderer
, 
 954                         GdkRectangle            
*background_area
, 
 955                         GdkRectangle            
*cell_area
, 
 956                         GtkCellRendererState     flags 
) 
 958     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
 959     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
 962     gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
, 
 968     rect
.x 
+= cell_area
->x
; 
 969     rect
.y 
+= cell_area
->y
; 
 970     rect
.width  
-= renderer
->xpad 
* 2; 
 971     rect
.height 
-= renderer
->ypad 
* 2; 
 973     wxRect 
renderrect( rect
.x
, rect
.y
, rect
.width
, rect
.height 
); 
 975     wxDataViewModel 
*model 
= cell
->GetOwner()->GetOwner()->GetModel(); 
 977     GtkTreePath 
*treepath 
= gtk_tree_path_new_from_string( path 
); 
 980     gtk_tree_path_free( treepath 
); 
 982     unsigned int model_col 
= cell
->GetOwner()->GetModelColumn(); 
 988         // activated by <ENTER> 
 989         if (cell
->Activate( renderrect
, model
, item
, model_col 
)) 
 994     else if (event
->type 
== GDK_BUTTON_PRESS
) 
 996         GdkEventButton 
*button_event 
= (GdkEventButton
*) event
; 
 997         wxPoint 
pt( ((int) button_event
->x
) - renderrect
.x
, 
 998                     ((int) button_event
->y
) - renderrect
.y 
); 
1001         if (button_event
->button 
== 1) 
1003             if (cell
->LeftClick( pt
, renderrect
, model
, item
, model_col 
)) 
1005             // TODO: query system double-click time 
1006             if (button_event
->time 
- wxrenderer
->last_click 
< 400) 
1007                 if (cell
->Activate( renderrect
, model
, item
, model_col 
)) 
1010         if (button_event
->button 
== 3) 
1012             if (cell
->RightClick( pt
, renderrect
, model
, item
, model_col 
)) 
1016         wxrenderer
->last_click 
= button_event
->time
; 
1024 // --------------------------------------------------------- 
1025 // wxGtkDataViewModelNotifier 
1026 // --------------------------------------------------------- 
1028 class wxGtkDataViewModelNotifier
: public wxDataViewModelNotifier
 
1031     wxGtkDataViewModelNotifier( GtkWxTreeModel  
*wxgtk_model
, 
1032                                 wxDataViewModel 
*wx_model
, 
1033                                 wxDataViewCtrl  
*ctrl 
); 
1034     ~wxGtkDataViewModelNotifier(); 
1036     virtual bool ItemAdded( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
); 
1037     virtual bool ItemDeleted( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
); 
1038     virtual bool ItemChanged( const wxDataViewItem 
&item 
); 
1039     virtual bool ValueChanged( const wxDataViewItem 
&item
, unsigned int col 
); 
1040     virtual bool Cleared(); 
1041     virtual void Resort(); 
1043     GtkWxTreeModel      
*m_wxgtk_model
; 
1044     wxDataViewModel     
*m_wx_model
; 
1045     wxDataViewCtrl      
*m_owner
; 
1048 // --------------------------------------------------------- 
1049 // wxGtkDataViewListModelNotifier 
1050 // --------------------------------------------------------- 
1052 wxGtkDataViewModelNotifier::wxGtkDataViewModelNotifier( 
1053     GtkWxTreeModel
* wxgtk_model
, wxDataViewModel 
*wx_model
, 
1054     wxDataViewCtrl 
*ctrl 
) 
1056     m_wxgtk_model 
= wxgtk_model
; 
1057     m_wx_model 
= wx_model
; 
1061 wxGtkDataViewModelNotifier::~wxGtkDataViewModelNotifier() 
1064     m_wxgtk_model 
= NULL
; 
1067 bool wxGtkDataViewModelNotifier::ItemAdded( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
) 
1069     m_owner
->GtkGetInternal()->ItemAdded( parent
, item 
); 
1072     iter
.stamp 
= m_wxgtk_model
->stamp
; 
1073     iter
.user_data 
= (gpointer
) item
.GetID(); 
1075     GtkTreePath 
*path 
= wxgtk_tree_model_get_path(  
1076         GTK_TREE_MODEL(m_wxgtk_model
), &iter 
); 
1077     gtk_tree_model_row_inserted(  
1078         GTK_TREE_MODEL(m_wxgtk_model
), path
, &iter
); 
1079     gtk_tree_path_free (path
); 
1084 bool wxGtkDataViewModelNotifier::ItemDeleted( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
) 
1087     iter
.stamp 
= m_wxgtk_model
->stamp
; 
1088     iter
.user_data 
= (gpointer
) item
.GetID(); 
1090     GtkTreePath 
*path 
= wxgtk_tree_model_get_path(  
1091         GTK_TREE_MODEL(m_wxgtk_model
), &iter 
); 
1092     gtk_tree_model_row_deleted( 
1093         GTK_TREE_MODEL(m_wxgtk_model
), path 
); 
1094     gtk_tree_path_free (path
); 
1096     m_owner
->GtkGetInternal()->ItemDeleted( parent
, item 
); 
1101 void wxGtkDataViewModelNotifier::Resort() 
1103     m_owner
->GtkGetInternal()->Resort(); 
1106 bool wxGtkDataViewModelNotifier::ItemChanged( const wxDataViewItem 
&item 
) 
1109     iter
.stamp 
= m_wxgtk_model
->stamp
; 
1110     iter
.user_data 
= (gpointer
) item
.GetID(); 
1112     GtkTreePath 
*path 
= wxgtk_tree_model_get_path(  
1113         GTK_TREE_MODEL(m_wxgtk_model
), &iter 
); 
1114     gtk_tree_model_row_changed( 
1115         GTK_TREE_MODEL(m_wxgtk_model
), path
, &iter 
); 
1116     gtk_tree_path_free (path
); 
1118     m_owner
->GtkGetInternal()->ItemChanged( item 
); 
1123 bool wxGtkDataViewModelNotifier::ValueChanged( const wxDataViewItem 
&item
, unsigned int model_col 
) 
1125     // This adds GTK+'s missing MVC logic for ValueChanged 
1127     for (index 
= 0; index 
< m_owner
->GetColumnCount(); index
++) 
1129         wxDataViewColumn 
*column 
= m_owner
->GetColumn( index 
); 
1130         if (column
->GetModelColumn() == model_col
) 
1132             GtkTreeView 
*widget 
= GTK_TREE_VIEW(m_owner
->m_treeview
); 
1133             GtkTreeViewColumn 
*gcolumn 
= GTK_TREE_VIEW_COLUMN(column
->GetGtkHandle()); 
1137             iter
.stamp 
= m_wxgtk_model
->stamp
; 
1138             iter
.user_data 
= (gpointer
) item
.GetID(); 
1139             GtkTreePath 
*path 
= wxgtk_tree_model_get_path(  
1140                 GTK_TREE_MODEL(m_wxgtk_model
), &iter 
); 
1141             GdkRectangle cell_area
; 
1142             gtk_tree_view_get_cell_area( widget
, path
, gcolumn
, &cell_area 
); 
1143             gtk_tree_path_free( path 
); 
1145             GtkAdjustment
* hadjust 
= gtk_tree_view_get_hadjustment( widget 
); 
1146             double d 
= gtk_adjustment_get_value( hadjust 
); 
1147             int xdiff 
= (int) d
; 
1149             int ydiff 
= gcolumn
->button
->allocation
.height
; 
1151             gtk_widget_queue_draw_area( GTK_WIDGET(widget
), 
1152                 cell_area
.x 
- xdiff
, ydiff 
+ cell_area
.y
, cell_area
.width
, cell_area
.height 
); 
1154             m_owner
->GtkGetInternal()->ValueChanged( item
, model_col 
); 
1163 bool wxGtkDataViewModelNotifier::Cleared() 
1165     // TODO: delete everything 
1167     m_owner
->GtkGetInternal()->Cleared(); 
1172 // --------------------------------------------------------- 
1173 // wxDataViewRenderer 
1174 // --------------------------------------------------------- 
1176 static gpointer s_user_data 
= NULL
; 
1179 wxgtk_cell_editable_editing_done( GtkCellEditable 
*editable
,  
1180                                   wxDataViewRenderer 
*wxrenderer 
) 
1182     wxDataViewColumn 
*column 
= wxrenderer
->GetOwner(); 
1183     wxDataViewCtrl 
*dv 
= column
->GetOwner(); 
1184     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_DONE
, dv
->GetId() ); 
1185     event
.SetDataViewColumn( column 
); 
1186     event
.SetModel( dv
->GetModel() ); 
1187     wxDataViewItem 
item( s_user_data 
); 
1188     event
.SetItem( item 
); 
1189     dv
->GetEventHandler()->ProcessEvent( event 
); 
1193 wxgtk_renderer_editing_started( GtkCellRenderer 
*cell
, GtkCellEditable 
*editable
, 
1194                                 gchar 
*path
, wxDataViewRenderer 
*wxrenderer 
) 
1196     wxDataViewColumn 
*column 
= wxrenderer
->GetOwner(); 
1197     wxDataViewCtrl 
*dv 
= column
->GetOwner(); 
1198     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_STARTED
, dv
->GetId() ); 
1199     event
.SetDataViewColumn( column 
); 
1200     event
.SetModel( dv
->GetModel() ); 
1201     GtkTreePath 
*tree_path 
= gtk_tree_path_new_from_string( path 
); 
1203     dv
->GtkGetInternal()->get_iter( &iter
, tree_path 
); 
1204     gtk_tree_path_free( tree_path 
); 
1205     wxDataViewItem 
item( iter
.user_data 
); 
1206     event
.SetItem( item 
); 
1207     dv
->GetEventHandler()->ProcessEvent( event 
); 
1209     if (GTK_IS_CELL_EDITABLE(editable
)) 
1211         s_user_data 
= iter
.user_data
; 
1213         g_signal_connect (GTK_CELL_EDITABLE (editable
), "editing_done", 
1214             G_CALLBACK (wxgtk_cell_editable_editing_done
), 
1215             (gpointer
) wxrenderer 
); 
1221 IMPLEMENT_ABSTRACT_CLASS(wxDataViewRenderer
, wxDataViewRendererBase
) 
1223 wxDataViewRenderer::wxDataViewRenderer( const wxString 
&varianttype
, wxDataViewCellMode mode
, 
1225     wxDataViewRendererBase( varianttype
, mode
, align 
) 
1229     // NOTE: SetMode() and SetAlignment() needs to be called in the renderer's ctor, 
1230     //       after the m_renderer pointer has been initialized 
1233 void wxDataViewRenderer::GtkInitHandlers() 
1235     if (!gtk_check_version(2,6,0)) 
1237         g_signal_connect (GTK_CELL_RENDERER(m_renderer
), "editing_started", 
1238                     G_CALLBACK (wxgtk_renderer_editing_started
), 
1243 void wxDataViewRenderer::SetMode( wxDataViewCellMode mode 
) 
1245     GtkCellRendererMode gtkMode
; 
1248     case wxDATAVIEW_CELL_INERT
: 
1249         gtkMode 
= GTK_CELL_RENDERER_MODE_INERT
; 
1251     case wxDATAVIEW_CELL_ACTIVATABLE
: 
1252         gtkMode 
= GTK_CELL_RENDERER_MODE_ACTIVATABLE
; 
1254     case wxDATAVIEW_CELL_EDITABLE
: 
1255         gtkMode 
= GTK_CELL_RENDERER_MODE_EDITABLE
; 
1259     GValue gvalue 
= { 0, }; 
1260     g_value_init( &gvalue
, gtk_cell_renderer_mode_get_type() ); 
1261     g_value_set_enum( &gvalue
, gtkMode 
); 
1262     g_object_set_property( G_OBJECT(m_renderer
), "mode", &gvalue 
); 
1263     g_value_unset( &gvalue 
); 
1266 wxDataViewCellMode 
wxDataViewRenderer::GetMode() const 
1268     wxDataViewCellMode ret
; 
1271     g_object_get( G_OBJECT(m_renderer
), "mode", &gvalue
, NULL
); 
1273     switch (g_value_get_enum(&gvalue
)) 
1275     case GTK_CELL_RENDERER_MODE_INERT
: 
1276         ret 
= wxDATAVIEW_CELL_INERT
; 
1278     case GTK_CELL_RENDERER_MODE_ACTIVATABLE
: 
1279         ret 
= wxDATAVIEW_CELL_ACTIVATABLE
; 
1281     case GTK_CELL_RENDERER_MODE_EDITABLE
: 
1282         ret 
= wxDATAVIEW_CELL_EDITABLE
; 
1286     g_value_unset( &gvalue 
); 
1291 void wxDataViewRenderer::SetAlignment( int align 
) 
1293     // horizontal alignment: 
1295     gfloat xalign 
= 0.0; 
1296     if (align 
& wxALIGN_RIGHT
) 
1298     else if (align 
& wxALIGN_CENTER_HORIZONTAL
) 
1301     GValue gvalue 
= { 0, }; 
1302     g_value_init( &gvalue
, G_TYPE_FLOAT 
); 
1303     g_value_set_float( &gvalue
, xalign 
); 
1304     g_object_set_property( G_OBJECT(m_renderer
), "xalign", &gvalue 
); 
1305     g_value_unset( &gvalue 
); 
1307     // vertical alignment: 
1309     gfloat yalign 
= 0.0; 
1310     if (align 
& wxALIGN_BOTTOM
) 
1312     else if (align 
& wxALIGN_CENTER_VERTICAL
) 
1315     GValue gvalue2 
= { 0, }; 
1316     g_value_init( &gvalue2
, G_TYPE_FLOAT 
); 
1317     g_value_set_float( &gvalue2
, yalign 
); 
1318     g_object_set_property( G_OBJECT(m_renderer
), "yalign", &gvalue2 
); 
1319     g_value_unset( &gvalue2 
); 
1322 int wxDataViewRenderer::GetAlignment() const 
1327     // horizontal alignment: 
1329     g_object_get( G_OBJECT(m_renderer
), "xalign", &gvalue
, NULL 
); 
1330     float xalign 
= g_value_get_float( &gvalue 
); 
1332         ret 
|= wxALIGN_LEFT
; 
1333     else if (xalign 
== 0.5) 
1334         ret 
|= wxALIGN_CENTER_HORIZONTAL
; 
1336         ret 
|= wxALIGN_RIGHT
; 
1337     g_value_unset( &gvalue 
); 
1340     // vertical alignment: 
1342     g_object_get( G_OBJECT(m_renderer
), "yalign", &gvalue
, NULL 
); 
1343     float yalign 
= g_value_get_float( &gvalue 
); 
1346     else if (yalign 
== 0.5) 
1347         ret 
|= wxALIGN_CENTER_VERTICAL
; 
1349         ret 
|= wxALIGN_BOTTOM
; 
1350     g_value_unset( &gvalue 
); 
1357 // --------------------------------------------------------- 
1358 // wxDataViewTextRenderer 
1359 // --------------------------------------------------------- 
1362 static void wxGtkTextRendererEditedCallback( GtkCellRendererText 
*renderer
, 
1363     gchar 
*arg1
, gchar 
*arg2
, gpointer user_data 
); 
1366 static void wxGtkTextRendererEditedCallback( GtkCellRendererText 
*renderer
, 
1367     gchar 
*arg1
, gchar 
*arg2
, gpointer user_data 
) 
1369     wxDataViewTextRenderer 
*cell 
= (wxDataViewTextRenderer
*) user_data
; 
1371     wxString tmp 
= wxGTK_CONV_BACK_FONT(arg2
, cell
->GetOwner()->GetOwner()->GetFont()); 
1372     wxVariant value 
= tmp
; 
1373     if (!cell
->Validate( value 
)) 
1376     wxDataViewModel 
*model 
= cell
->GetOwner()->GetOwner()->GetModel(); 
1378     GtkTreePath 
*path 
= gtk_tree_path_new_from_string( arg1 
); 
1380     cell
->GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter
, path 
); 
1381     wxDataViewItem 
item( (void*) iter
.user_data 
);; 
1382     gtk_tree_path_free( path 
); 
1384     unsigned int model_col 
= cell
->GetOwner()->GetModelColumn(); 
1386     model
->SetValue( value
, item
, model_col 
); 
1387     model
->ValueChanged( item
, model_col 
); 
1390 IMPLEMENT_CLASS(wxDataViewTextRenderer
, wxDataViewRenderer
) 
1392 wxDataViewTextRenderer::wxDataViewTextRenderer( const wxString 
&varianttype
, wxDataViewCellMode mode
, 
1394     wxDataViewRenderer( varianttype
, mode
, align 
) 
1396     m_renderer 
= (GtkCellRenderer
*) gtk_cell_renderer_text_new(); 
1398     if (mode 
& wxDATAVIEW_CELL_EDITABLE
) 
1400         GValue gvalue 
= { 0, }; 
1401         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1402         g_value_set_boolean( &gvalue
, true ); 
1403         g_object_set_property( G_OBJECT(m_renderer
), "editable", &gvalue 
); 
1404         g_value_unset( &gvalue 
); 
1406         g_signal_connect_after( m_renderer
, "edited", G_CALLBACK(wxGtkTextRendererEditedCallback
), this ); 
1412     SetAlignment(align
); 
1415 bool wxDataViewTextRenderer::SetValue( const wxVariant 
&value 
) 
1417     wxString tmp 
= value
; 
1419     GValue gvalue 
= { 0, }; 
1420     g_value_init( &gvalue
, G_TYPE_STRING 
); 
1421     g_value_set_string( &gvalue
, wxGTK_CONV_FONT( tmp
, GetOwner()->GetOwner()->GetFont() ) ); 
1422     g_object_set_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
1423     g_value_unset( &gvalue 
); 
1428 bool wxDataViewTextRenderer::GetValue( wxVariant 
&value 
) const 
1430     GValue gvalue 
= { 0, }; 
1431     g_value_init( &gvalue
, G_TYPE_STRING 
); 
1432     g_object_get_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
1433     wxString tmp 
= wxGTK_CONV_BACK_FONT( g_value_get_string( &gvalue 
), 
1434         wx_const_cast(wxDataViewTextRenderer
*, this)->GetOwner()->GetOwner()->GetFont() ); 
1435     g_value_unset( &gvalue 
); 
1442 void wxDataViewTextRenderer::SetAlignment( int align 
) 
1444     wxDataViewRenderer::SetAlignment(align
); 
1446     if (gtk_check_version(2,10,0)) 
1449     // horizontal alignment: 
1450     PangoAlignment pangoAlign 
= PANGO_ALIGN_LEFT
; 
1451     if (align 
& wxALIGN_RIGHT
) 
1452         pangoAlign 
= PANGO_ALIGN_RIGHT
; 
1453     else if (align 
& wxALIGN_CENTER_HORIZONTAL
) 
1454         pangoAlign 
= PANGO_ALIGN_CENTER
; 
1456     GValue gvalue 
= { 0, }; 
1457     g_value_init( &gvalue
, gtk_cell_renderer_mode_get_type() ); 
1458     g_value_set_enum( &gvalue
, pangoAlign 
); 
1459     g_object_set_property( G_OBJECT(m_renderer
), "alignment", &gvalue 
); 
1460     g_value_unset( &gvalue 
); 
1463 // --------------------------------------------------------- 
1464 // wxDataViewBitmapRenderer 
1465 // --------------------------------------------------------- 
1467 IMPLEMENT_CLASS(wxDataViewBitmapRenderer
, wxDataViewRenderer
) 
1469 wxDataViewBitmapRenderer::wxDataViewBitmapRenderer( const wxString 
&varianttype
, wxDataViewCellMode mode
, 
1471     wxDataViewRenderer( varianttype
, mode
, align 
) 
1473     m_renderer 
= (GtkCellRenderer
*) gtk_cell_renderer_pixbuf_new(); 
1476     SetAlignment(align
); 
1479 bool wxDataViewBitmapRenderer::SetValue( const wxVariant 
&value 
) 
1481     if (value
.GetType() == wxT("wxBitmap")) 
1486         // This may create a Pixbuf representation in the 
1487         // wxBitmap object (and it will stay there) 
1488         GdkPixbuf 
*pixbuf 
= bitmap
.GetPixbuf(); 
1490         GValue gvalue 
= { 0, }; 
1491         g_value_init( &gvalue
, G_TYPE_OBJECT 
); 
1492         g_value_set_object( &gvalue
, pixbuf 
); 
1493         g_object_set_property( G_OBJECT(m_renderer
), "pixbuf", &gvalue 
); 
1494         g_value_unset( &gvalue 
); 
1499     if (value
.GetType() == wxT("wxIcon")) 
1504         // This may create a Pixbuf representation in the 
1505         // wxBitmap object (and it will stay there) 
1506         GdkPixbuf 
*pixbuf 
= bitmap
.GetPixbuf(); 
1508         GValue gvalue 
= { 0, }; 
1509         g_value_init( &gvalue
, G_TYPE_OBJECT 
); 
1510         g_value_set_object( &gvalue
, pixbuf 
); 
1511         g_object_set_property( G_OBJECT(m_renderer
), "pixbuf", &gvalue 
); 
1512         g_value_unset( &gvalue 
); 
1520 bool wxDataViewBitmapRenderer::GetValue( wxVariant 
&value 
) const 
1525 // --------------------------------------------------------- 
1526 // wxDataViewToggleRenderer 
1527 // --------------------------------------------------------- 
1530 static void wxGtkToggleRendererToggledCallback( GtkCellRendererToggle 
*renderer
, 
1531     gchar 
*path
, gpointer user_data 
); 
1534 static void wxGtkToggleRendererToggledCallback( GtkCellRendererToggle 
*renderer
, 
1535     gchar 
*path
, gpointer user_data 
) 
1537     wxDataViewToggleRenderer 
*cell 
= (wxDataViewToggleRenderer
*) user_data
; 
1540     GValue gvalue 
= { 0, }; 
1541     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1542     g_object_get_property( G_OBJECT(renderer
), "active", &gvalue 
); 
1543     bool tmp 
= g_value_get_boolean( &gvalue 
); 
1544     g_value_unset( &gvalue 
); 
1548     wxVariant value 
= tmp
; 
1549     if (!cell
->Validate( value 
)) 
1552     wxDataViewModel 
*model 
= cell
->GetOwner()->GetOwner()->GetModel(); 
1554     GtkTreePath 
*gtk_path 
= gtk_tree_path_new_from_string( path 
); 
1556     cell
->GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter
, gtk_path 
); 
1557     wxDataViewItem 
item( (void*) iter
.user_data 
);; 
1558     gtk_tree_path_free( gtk_path 
); 
1560     unsigned int model_col 
= cell
->GetOwner()->GetModelColumn(); 
1562     model
->SetValue( value
, item
, model_col 
); 
1563     model
->ValueChanged( item
, model_col 
); 
1566 IMPLEMENT_CLASS(wxDataViewToggleRenderer
, wxDataViewRenderer
) 
1568 wxDataViewToggleRenderer::wxDataViewToggleRenderer( const wxString 
&varianttype
, 
1569                                                     wxDataViewCellMode mode
, int align 
) : 
1570     wxDataViewRenderer( varianttype
, mode
, align 
) 
1572     m_renderer 
= (GtkCellRenderer
*) gtk_cell_renderer_toggle_new(); 
1574     if (mode 
& wxDATAVIEW_CELL_ACTIVATABLE
) 
1576         g_signal_connect_after( m_renderer
, "toggled", 
1577                                 G_CALLBACK(wxGtkToggleRendererToggledCallback
), this ); 
1581         GValue gvalue 
= { 0, }; 
1582         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1583         g_value_set_boolean( &gvalue
, false ); 
1584         g_object_set_property( G_OBJECT(m_renderer
), "activatable", &gvalue 
); 
1585         g_value_unset( &gvalue 
); 
1589     SetAlignment(align
); 
1592 bool wxDataViewToggleRenderer::SetValue( const wxVariant 
&value 
) 
1596     GValue gvalue 
= { 0, }; 
1597     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1598     g_value_set_boolean( &gvalue
, tmp 
); 
1599     g_object_set_property( G_OBJECT(m_renderer
), "active", &gvalue 
); 
1600     g_value_unset( &gvalue 
); 
1605 bool wxDataViewToggleRenderer::GetValue( wxVariant 
&value 
) const 
1607     GValue gvalue 
= { 0, }; 
1608     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1609     g_object_get_property( G_OBJECT(m_renderer
), "active", &gvalue 
); 
1610     bool tmp 
= g_value_get_boolean( &gvalue 
); 
1611     g_value_unset( &gvalue 
); 
1618 // --------------------------------------------------------- 
1619 // wxDataViewCustomRenderer 
1620 // --------------------------------------------------------- 
1622 class wxDataViewCtrlDC
: public wxWindowDC
 
1625     wxDataViewCtrlDC( wxDataViewCtrl 
*window 
) 
1627         GtkWidget 
*widget 
= window
->m_treeview
; 
1631         m_context 
= window
->GtkGetPangoDefaultContext(); 
1632         m_layout 
= pango_layout_new( m_context 
); 
1633         m_fontdesc 
= pango_font_description_copy( widget
->style
->font_desc 
); 
1635         m_cmap 
= gtk_widget_get_colormap( widget 
? widget 
: window
->m_widget 
); 
1637         // Set m_window later 
1639         // m_owner = window; 
1643 // --------------------------------------------------------- 
1644 // wxDataViewCustomRenderer 
1645 // --------------------------------------------------------- 
1647 IMPLEMENT_CLASS(wxDataViewCustomRenderer
, wxDataViewRenderer
) 
1649 wxDataViewCustomRenderer::wxDataViewCustomRenderer( const wxString 
&varianttype
, 
1650                                                     wxDataViewCellMode mode
, int align
, 
1652     wxDataViewRenderer( varianttype
, mode
, align 
) 
1662 bool wxDataViewCustomRenderer::Init(wxDataViewCellMode mode
, int align
) 
1664     GtkWxCellRenderer 
*renderer 
= (GtkWxCellRenderer 
*) gtk_wx_cell_renderer_new(); 
1665     renderer
->cell 
= this; 
1667     m_renderer 
= (GtkCellRenderer
*) renderer
; 
1670     SetAlignment(align
); 
1677 wxDataViewCustomRenderer::~wxDataViewCustomRenderer() 
1683 wxDC 
*wxDataViewCustomRenderer::GetDC() 
1687         if (GetOwner() == NULL
) 
1689         if (GetOwner()->GetOwner() == NULL
) 
1691         m_dc 
= new wxDataViewCtrlDC( GetOwner()->GetOwner() ); 
1697 // --------------------------------------------------------- 
1698 // wxDataViewProgressRenderer 
1699 // --------------------------------------------------------- 
1701 IMPLEMENT_CLASS(wxDataViewProgressRenderer
, wxDataViewCustomRenderer
) 
1703 wxDataViewProgressRenderer::wxDataViewProgressRenderer( const wxString 
&label
, 
1704     const wxString 
&varianttype
, wxDataViewCellMode mode
, int align 
) : 
1705     wxDataViewCustomRenderer( varianttype
, mode
, align
, true ) 
1711     if (!gtk_check_version(2,6,0)) 
1713         m_renderer 
= (GtkCellRenderer
*) gtk_cell_renderer_progress_new(); 
1715         GValue gvalue 
= { 0, }; 
1716         g_value_init( &gvalue
, G_TYPE_STRING 
); 
1718         // FIXME: font encoding support 
1719         g_value_set_string( &gvalue
, wxGTK_CONV_SYS(m_label
) ); 
1720         g_object_set_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
1721         g_value_unset( &gvalue 
); 
1724         SetAlignment(align
); 
1729         // Use custom cell code 
1730         wxDataViewCustomRenderer::Init(mode
, align
); 
1734 wxDataViewProgressRenderer::~wxDataViewProgressRenderer() 
1738 bool wxDataViewProgressRenderer::SetValue( const wxVariant 
&value 
) 
1741     if (!gtk_check_version(2,6,0)) 
1743         gint tmp 
= (long) value
; 
1744         GValue gvalue 
= { 0, }; 
1745         g_value_init( &gvalue
, G_TYPE_INT 
); 
1746         g_value_set_int( &gvalue
, tmp 
); 
1747         g_object_set_property( G_OBJECT(m_renderer
), "value", &gvalue 
); 
1748         g_value_unset( &gvalue 
); 
1753         m_value 
= (long) value
; 
1755         if (m_value 
< 0) m_value 
= 0; 
1756         if (m_value 
> 100) m_value 
= 100; 
1762 bool wxDataViewProgressRenderer::GetValue( wxVariant 
&value 
) const 
1767 bool wxDataViewProgressRenderer::Render( wxRect cell
, wxDC 
*dc
, int state 
) 
1769     double pct 
= (double)m_value 
/ 100.0; 
1771     bar
.width 
= (int)(cell
.width 
* pct
); 
1772     dc
->SetPen( *wxTRANSPARENT_PEN 
); 
1773     dc
->SetBrush( *wxBLUE_BRUSH 
); 
1774     dc
->DrawRectangle( bar 
); 
1776     dc
->SetBrush( *wxTRANSPARENT_BRUSH 
); 
1777     dc
->SetPen( *wxBLACK_PEN 
); 
1778     dc
->DrawRectangle( cell 
); 
1783 wxSize 
wxDataViewProgressRenderer::GetSize() const 
1785     return wxSize(40,12); 
1788 // --------------------------------------------------------- 
1789 // wxDataViewDateRenderer 
1790 // --------------------------------------------------------- 
1792 class wxDataViewDateRendererPopupTransient
: public wxPopupTransientWindow
 
1795     wxDataViewDateRendererPopupTransient( wxWindow
* parent
, wxDateTime 
*value
, 
1796         wxDataViewModel 
*model
, const wxDataViewItem 
&item
, unsigned int col 
) : 
1797         wxPopupTransientWindow( parent
, wxBORDER_SIMPLE 
) 
1802         m_cal 
= new wxCalendarCtrl( this, -1, *value 
); 
1803         wxBoxSizer 
*sizer 
= new wxBoxSizer( wxHORIZONTAL 
); 
1804         sizer
->Add( m_cal
, 1, wxGROW 
); 
1809     virtual void OnDismiss() 
1813     void OnCalendar( wxCalendarEvent 
&event 
); 
1815     wxCalendarCtrl   
*m_cal
; 
1816     wxDataViewModel  
*m_model
; 
1817     wxDataViewItem    m_item
; 
1821     DECLARE_EVENT_TABLE() 
1824 BEGIN_EVENT_TABLE(wxDataViewDateRendererPopupTransient
,wxPopupTransientWindow
) 
1825     EVT_CALENDAR( -1, wxDataViewDateRendererPopupTransient::OnCalendar 
) 
1828 void wxDataViewDateRendererPopupTransient::OnCalendar( wxCalendarEvent 
&event 
) 
1830     wxDateTime date 
= event
.GetDate(); 
1831     wxVariant value 
= date
; 
1832     m_model
->SetValue( value
, m_item
, m_col 
); 
1833     m_model
->ValueChanged( m_item
, m_col 
); 
1837 IMPLEMENT_CLASS(wxDataViewDateRenderer
, wxDataViewCustomRenderer
) 
1839 wxDataViewDateRenderer::wxDataViewDateRenderer( const wxString 
&varianttype
, 
1840                         wxDataViewCellMode mode
, int align 
) : 
1841     wxDataViewCustomRenderer( varianttype
, mode
, align 
) 
1844     SetAlignment(align
); 
1847 bool wxDataViewDateRenderer::SetValue( const wxVariant 
&value 
) 
1849     m_date 
= value
.GetDateTime(); 
1854 bool wxDataViewDateRenderer::GetValue( wxVariant 
&value 
) const 
1859 bool wxDataViewDateRenderer::Render( wxRect cell
, wxDC 
*dc
, int state 
) 
1861     dc
->SetFont( GetOwner()->GetOwner()->GetFont() ); 
1862     wxString tmp 
= m_date
.FormatDate(); 
1863     dc
->DrawText( tmp
, cell
.x
, cell
.y 
); 
1868 wxSize 
wxDataViewDateRenderer::GetSize() const 
1870     wxString tmp 
= m_date
.FormatDate(); 
1872     GetView()->GetTextExtent( tmp
, &x
, &y
, &d 
); 
1873     return wxSize(x
,y
+d
); 
1876 bool wxDataViewDateRenderer::Activate( wxRect cell
, wxDataViewModel 
*model
, 
1877                                        const wxDataViewItem 
&item
, unsigned int col 
) 
1880     model
->GetValue( variant
, item
, col 
); 
1881     wxDateTime value 
= variant
.GetDateTime(); 
1883     wxDataViewDateRendererPopupTransient 
*popup 
= new wxDataViewDateRendererPopupTransient( 
1884         GetOwner()->GetOwner()->GetParent(), &value
, model
, item
, col 
); 
1885     wxPoint pos 
= wxGetMousePosition(); 
1888     popup
->Popup( popup
->m_cal 
); 
1893 // --------------------------------------------------------- 
1895 // --------------------------------------------------------- 
1899 gtk_dataview_header_button_press_callback( GtkWidget 
*widget
, 
1900                                            GdkEventButton 
*gdk_event
, 
1901                                            wxDataViewColumn 
*column 
) 
1903     if (gdk_event
->type 
!= GDK_BUTTON_PRESS
) 
1906     if (gdk_event
->button 
== 1) 
1908         wxDataViewCtrl 
*dv 
= column
->GetOwner(); 
1909         wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK
, dv
->GetId() ); 
1910         event
.SetDataViewColumn( column 
); 
1911         event
.SetModel( dv
->GetModel() ); 
1912         if (dv
->GetEventHandler()->ProcessEvent( event 
)) 
1920 static void wxGtkTreeCellDataFunc( GtkTreeViewColumn 
*column
, 
1921                             GtkCellRenderer 
*cell
, 
1922                             GtkTreeModel 
*model
, 
1928 static void wxGtkTreeCellDataFunc( GtkTreeViewColumn 
*column
, 
1929                             GtkCellRenderer 
*renderer
, 
1930                             GtkTreeModel 
*model
, 
1934     g_return_if_fail (GTK_IS_WX_TREE_MODEL (model
)); 
1935     GtkWxTreeModel 
*tree_model 
= (GtkWxTreeModel 
*) model
; 
1937     wxDataViewRenderer 
*cell 
= (wxDataViewRenderer
*) data
; 
1939     wxDataViewItem 
item( (void*) iter
->user_data 
); 
1942     tree_model
->internal
->GetDataViewModel()->GetValue( value
, item
, cell
->GetOwner()->GetModelColumn() ); 
1944     if (value
.GetType() != cell
->GetVariantType()) 
1945         wxLogError( wxT("Wrong type, required: %s but: %s"), 
1946                     value
.GetType().c_str(), 
1947                     cell
->GetVariantType().c_str() ); 
1949     cell
->SetValue( value 
); 
1952     wxListItemAttr attr
; 
1953     tree_model
->model
->GetAttr( attr
, cell
->GetOwner()->GetModelColumn(), model_row 
); 
1955     if (attr
.HasBackgroundColour()) 
1957         wxColour colour 
= attr
.GetBackgroundColour(); 
1958         const GdkColor 
* const gcol 
= colour
.GetColor(); 
1960         GValue gvalue 
= { 0, }; 
1961         g_value_init( &gvalue
, GDK_TYPE_COLOR 
); 
1962         g_value_set_boxed( &gvalue
, gcol 
); 
1963         g_object_set_property( G_OBJECT(renderer
), "cell-background_gdk", &gvalue 
); 
1964         g_value_unset( &gvalue 
); 
1968         GValue gvalue 
= { 0, }; 
1969         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1970         g_value_set_boolean( &gvalue
, FALSE 
); 
1971         g_object_set_property( G_OBJECT(renderer
), "cell-background-set", &gvalue 
); 
1972         g_value_unset( &gvalue 
); 
1978 IMPLEMENT_CLASS(wxDataViewColumn
, wxDataViewColumnBase
) 
1980 wxDataViewColumn::wxDataViewColumn( const wxString 
&title
, wxDataViewRenderer 
*cell
, 
1981                                     unsigned int model_column
, int width
, 
1982                                     wxAlignment align
, int flags 
) : 
1983     wxDataViewColumnBase( title
, cell
, model_column
, width
, align
, flags 
) 
1985     Init( align
, flags
, width 
); 
1987     gtk_tree_view_column_set_clickable( GTK_TREE_VIEW_COLUMN(m_column
), TRUE 
); 
1991 wxDataViewColumn::wxDataViewColumn( const wxBitmap 
&bitmap
, wxDataViewRenderer 
*cell
, 
1992                                     unsigned int model_column
, int width
, 
1993                                     wxAlignment align
, int flags 
) : 
1994     wxDataViewColumnBase( bitmap
, cell
, model_column
, width
, align
, flags 
) 
1996     Init( align
, flags
, width 
); 
1998     SetBitmap( bitmap 
); 
2001 void wxDataViewColumn::Init(wxAlignment align
, int flags
, int width
) 
2003     m_isConnected 
= false; 
2005     GtkCellRenderer 
*renderer 
= (GtkCellRenderer 
*) GetRenderer()->GetGtkHandle(); 
2006     GtkTreeViewColumn 
*column 
= gtk_tree_view_column_new(); 
2007     m_column 
= (GtkWidget
*) column
; 
2010     SetAlignment( align 
); 
2012     // NOTE: we prefer not to call SetMinWidth(wxDVC_DEFAULT_MINWIDTH); 
2013     //       as GTK+ is smart and unless explicitely told, will set the minimal 
2014     //       width to the title's lenght, which is a better default 
2016     // the GTK_TREE_VIEW_COLUMN_FIXED is required by the "fixed height" mode 
2017     // that we use for the wxDataViewCtrl 
2018     gtk_tree_view_column_set_fixed_width( column
, width 
< 0 ? wxDVC_DEFAULT_WIDTH 
: width 
); 
2019     gtk_tree_view_column_set_sizing( column
, GTK_TREE_VIEW_COLUMN_FIXED 
); 
2021     gtk_tree_view_column_pack_end( column
, renderer
, TRUE 
); 
2023     gtk_tree_view_column_set_cell_data_func( column
, renderer
, 
2024         wxGtkTreeCellDataFunc
, (gpointer
) GetRenderer(), NULL 
); 
2027 wxDataViewColumn::~wxDataViewColumn() 
2031 void wxDataViewColumn::OnInternalIdle() 
2036     if (GTK_WIDGET_REALIZED(GetOwner()->m_treeview
)) 
2038         GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2041             g_signal_connect(column
->button
, "button_press_event", 
2042                       G_CALLBACK (gtk_dataview_header_button_press_callback
), this); 
2044             m_isConnected 
= true; 
2049 void wxDataViewColumn::SetOwner( wxDataViewCtrl 
*owner 
) 
2051     wxDataViewColumnBase::SetOwner( owner 
); 
2053     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2055     gtk_tree_view_column_set_title( column
, wxGTK_CONV_FONT(GetTitle(), GetOwner()->GetFont() ) ); 
2058 void wxDataViewColumn::SetTitle( const wxString 
&title 
) 
2060     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2064         // disconnect before column->button gets recreated 
2065         g_signal_handlers_disconnect_by_func( column
->button
, 
2066                       (GtkWidget
*) gtk_dataview_header_button_press_callback
, this); 
2068         m_isConnected 
= false; 
2071     // FIXME: can it really happen that we don't have the owner here?? 
2072     wxDataViewCtrl 
*ctrl 
= GetOwner(); 
2073     gtk_tree_view_column_set_title( column
, ctrl 
? wxGTK_CONV_FONT(title
, ctrl
->GetFont()) 
2074                                                  : wxGTK_CONV_SYS(title
) ); 
2076     gtk_tree_view_column_set_widget( column
, NULL 
); 
2079 wxString 
wxDataViewColumn::GetTitle() const 
2081     const gchar 
*str 
= gtk_tree_view_column_get_title( GTK_TREE_VIEW_COLUMN(m_column
) ); 
2082     return wxConvFileName
->cMB2WX(str
); 
2085 void wxDataViewColumn::SetBitmap( const wxBitmap 
&bitmap 
) 
2087     wxDataViewColumnBase::SetBitmap( bitmap 
); 
2089     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2092         GtkImage 
*gtk_image 
= GTK_IMAGE( gtk_image_new() ); 
2094         GdkBitmap 
*mask 
= (GdkBitmap 
*) NULL
; 
2095         if (bitmap
.GetMask()) 
2096             mask 
= bitmap
.GetMask()->GetBitmap(); 
2098         if (bitmap
.HasPixbuf()) 
2100             gtk_image_set_from_pixbuf(GTK_IMAGE(gtk_image
), 
2101                                       bitmap
.GetPixbuf()); 
2105             gtk_image_set_from_pixmap(GTK_IMAGE(gtk_image
), 
2106                                       bitmap
.GetPixmap(), mask
); 
2108         gtk_widget_show( GTK_WIDGET(gtk_image
) ); 
2110         gtk_tree_view_column_set_widget( column
, GTK_WIDGET(gtk_image
) ); 
2114         gtk_tree_view_column_set_widget( column
, NULL 
); 
2118 void wxDataViewColumn::SetHidden( bool hidden 
) 
2120     gtk_tree_view_column_set_visible( GTK_TREE_VIEW_COLUMN(m_column
), !hidden 
); 
2123 void wxDataViewColumn::SetResizeable( bool resizeable 
) 
2125     gtk_tree_view_column_set_resizable( GTK_TREE_VIEW_COLUMN(m_column
), resizeable 
); 
2128 void wxDataViewColumn::SetAlignment( wxAlignment align 
) 
2130     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2132     gfloat xalign 
= 0.0; 
2133     if (align 
== wxALIGN_RIGHT
) 
2135     if (align 
== wxALIGN_CENTER_HORIZONTAL 
|| 
2136         align 
== wxALIGN_CENTER
) 
2139     gtk_tree_view_column_set_alignment( column
, xalign 
); 
2142 wxAlignment 
wxDataViewColumn::GetAlignment() const 
2144     gfloat xalign 
= gtk_tree_view_column_get_alignment( GTK_TREE_VIEW_COLUMN(m_column
) ); 
2147         return wxALIGN_RIGHT
; 
2149         return wxALIGN_CENTER_HORIZONTAL
; 
2151     return wxALIGN_LEFT
; 
2154 void wxDataViewColumn::SetSortable( bool sortable 
) 
2156     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2160         gtk_tree_view_column_set_sort_column_id( column
, GetModelColumn() ); 
2164         gtk_tree_view_column_set_sort_column_id( column
, -1 ); 
2165         gtk_tree_view_column_set_sort_indicator( column
, FALSE 
); 
2169 bool wxDataViewColumn::IsSortable() const 
2171     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2172     return (gtk_tree_view_column_get_sort_column_id( column 
) != -1); 
2175 bool wxDataViewColumn::IsResizeable() const 
2177     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2178     return gtk_tree_view_column_get_resizable( column 
); 
2181 bool wxDataViewColumn::IsHidden() const 
2183     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2184     return !gtk_tree_view_column_get_visible( column 
); 
2187 void wxDataViewColumn::SetSortOrder( bool ascending 
) 
2189     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2192         gtk_tree_view_column_set_sort_order( column
, GTK_SORT_ASCENDING 
); 
2194         gtk_tree_view_column_set_sort_order( column
, GTK_SORT_DESCENDING 
); 
2196     gtk_tree_view_column_set_sort_indicator( column
, TRUE 
); 
2199 bool wxDataViewColumn::IsSortOrderAscending() const 
2201     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2203     return (gtk_tree_view_column_get_sort_order( column 
) != GTK_SORT_DESCENDING
); 
2206 void wxDataViewColumn::SetMinWidth( int width 
) 
2208     gtk_tree_view_column_set_min_width( GTK_TREE_VIEW_COLUMN(m_column
), width 
); 
2211 int wxDataViewColumn::GetMinWidth() const 
2213     return gtk_tree_view_column_get_min_width( GTK_TREE_VIEW_COLUMN(m_column
) ); 
2216 int wxDataViewColumn::GetWidth() const 
2218     return gtk_tree_view_column_get_width( GTK_TREE_VIEW_COLUMN(m_column
) ); 
2221 void wxDataViewColumn::SetWidth( int width 
) 
2223     gtk_tree_view_column_set_fixed_width( GTK_TREE_VIEW_COLUMN(m_column
), width 
); 
2227 //----------------------------------------------------------------------------- 
2228 // wxGtkTreeModelNode 
2229 //----------------------------------------------------------------------------- 
2231 void wxGtkTreeModelNode::Resort() 
2233     size_t child_count 
= GetChildCount(); 
2234     if (child_count 
== 0) 
2237     size_t node_count 
= GetNodesCount(); 
2239     if (child_count 
== 1) 
2241         if (node_count 
== 1) 
2243             wxGtkTreeModelNode 
*node 
= m_nodes
.Item( 0 ); 
2249     wxGtkTreeModelChildren temp
; 
2250     WX_APPEND_ARRAY( temp
, m_children 
); 
2252     g_internal 
= m_internal
; 
2253     m_children
.Sort( &wxGtkTreeModelChildCmp 
); 
2255     gint 
*new_order 
= new gint
[child_count
]; 
2258     for (pos 
= 0; pos 
< child_count
; pos
++) 
2260         void *id 
= m_children
.Item( pos 
); 
2261         int old_pos 
= temp
.Index( id 
); 
2262         new_order
[pos
] = old_pos
; 
2265     GtkTreeModel 
*gtk_tree_model 
= GTK_TREE_MODEL( m_internal
->GetGtkModel() ); 
2268     iter
.user_data 
= GetItem().GetID(); 
2269     iter
.stamp 
= m_internal
->GetGtkModel()->stamp
; 
2271     GtkTreePath 
*path 
= m_internal
->get_path( &iter 
); 
2273     gtk_tree_model_rows_reordered( gtk_tree_model
, path
, &iter
, new_order 
); 
2275     gtk_tree_path_free (path
); 
2277     delete [] new_order
; 
2279     for (pos 
= 0; pos 
< node_count
; pos
++) 
2281         wxGtkTreeModelNode 
*node 
= m_nodes
.Item( pos 
); 
2286 //----------------------------------------------------------------------------- 
2287 // wxDataViewCtrlInternal 
2288 //----------------------------------------------------------------------------- 
2290 wxDataViewCtrlInternal::wxDataViewCtrlInternal( wxDataViewCtrl 
*owner
,  
2291     wxDataViewModel 
*wx_model
, GtkWxTreeModel 
*gtk_model 
) 
2294     m_wx_model 
= wx_model
;  
2295     m_gtk_model 
= gtk_model
;  
2297     m_sort_order 
= GTK_SORT_ASCENDING
; 
2302 wxDataViewCtrlInternal::~wxDataViewCtrlInternal() 
2304     g_object_unref( m_gtk_model 
); 
2307 void wxDataViewCtrlInternal::InitTree() 
2309     wxDataViewItem item
; 
2310     m_root 
= new wxGtkTreeModelNode( NULL
, item
, this ); 
2312     BuildBranch( m_root 
); 
2315 void wxDataViewCtrlInternal::BuildBranch( wxGtkTreeModelNode 
*node 
) 
2317     if (node
->GetChildCount() == 0) 
2319         wxDataViewItem child 
= m_wx_model
->GetFirstChild( node
->GetItem() ); 
2320         while (child
.IsOk()) 
2322             if (m_wx_model
->IsContainer( child 
)) 
2323                 node
->AddNode( new wxGtkTreeModelNode( node
, child
, this ) ); 
2325                 node
->AddLeave( child
.GetID() ); 
2327             // Don't send any events here 
2329             child 
= m_wx_model
->GetNextSibling( child 
); 
2334 void wxDataViewCtrlInternal::Resort() 
2339 bool wxDataViewCtrlInternal::ItemAdded( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
) 
2341     wxGtkTreeModelNode 
*parent_node 
= FindNode( parent 
); 
2342     if (m_wx_model
->IsContainer( item 
)) 
2343         parent_node
->AddNode( new wxGtkTreeModelNode( parent_node
, item
, this ) ); 
2345         parent_node
->AddLeave( item
.GetID() ); 
2347     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_ADDED
, m_owner
->GetId() ); 
2348     event
.SetEventObject( m_owner 
); 
2349     event
.SetModel( m_owner
->GetModel() ); 
2350     event
.SetItem( item 
); 
2351     m_owner
->GetEventHandler()->ProcessEvent( event 
); 
2356 bool wxDataViewCtrlInternal::ItemDeleted( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
) 
2358     wxGtkTreeModelNode 
*parent_node 
= FindNode( parent 
); 
2359     parent_node
->DeleteChild( item
.GetID() ); 
2361     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_DELETED
, m_owner
->GetId() ); 
2362     event
.SetEventObject( m_owner 
); 
2363     event
.SetModel( m_owner
->GetModel() ); 
2364     event
.SetItem( item 
); 
2365     m_owner
->GetEventHandler()->ProcessEvent( event 
); 
2370 bool wxDataViewCtrlInternal::ItemChanged( const wxDataViewItem 
&item 
) 
2372     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_CHANGED
, m_owner
->GetId() ); 
2373     event
.SetEventObject( m_owner 
); 
2374     event
.SetModel( m_owner
->GetModel() ); 
2375     event
.SetItem( item 
); 
2376     m_owner
->GetEventHandler()->ProcessEvent( event 
); 
2381 bool wxDataViewCtrlInternal::ValueChanged( const wxDataViewItem 
&item
, unsigned int col 
) 
2383     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_MODEL_VALUE_CHANGED
, m_owner
->GetId() ); 
2384     event
.SetEventObject( m_owner 
); 
2385     event
.SetModel( m_owner
->GetModel() ); 
2386     event
.SetColumn( col 
); 
2387     event
.SetItem( item 
); 
2388     m_owner
->GetEventHandler()->ProcessEvent( event 
); 
2393 bool wxDataViewCtrlInternal::Cleared() 
2395     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_MODEL_CLEARED
, m_owner
->GetId() ); 
2396     event
.SetEventObject( m_owner 
); 
2397     event
.SetModel( m_owner
->GetModel() ); 
2398     m_owner
->GetEventHandler()->ProcessEvent( event 
); 
2403 gboolean 
wxDataViewCtrlInternal::get_iter( GtkTreeIter 
*iter
, GtkTreePath 
*path 
) 
2405     int depth 
= gtk_tree_path_get_depth( path 
); 
2407     wxGtkTreeModelNode 
*node 
= m_root
; 
2410     for (i 
= 0; i 
< depth
; i
++)     
2412         BuildBranch( node 
); 
2414         gint pos 
= gtk_tree_path_get_indices (path
)[i
]; 
2415         if (pos 
< 0) return FALSE
; 
2416         if ((size_t)pos 
>= node
->GetChildCount()) return FALSE
; 
2418         void* id 
= node
->GetChildren().Item( (size_t) pos 
); 
2422             iter
->stamp 
= m_gtk_model
->stamp
; 
2423             iter
->user_data 
= id
; 
2427         size_t count 
= node
->GetNodes().GetCount(); 
2429         for (pos2 
= 0; pos2 
< count
; pos2
++) 
2431             wxGtkTreeModelNode 
*child_node 
= node
->GetNodes().Item( pos2 
); 
2432             if (child_node
->GetItem().GetID() == id
) 
2443 GtkTreePath 
*wxDataViewCtrlInternal::get_path( GtkTreeIter 
*iter 
) 
2445     GtkTreePath 
*retval 
= gtk_tree_path_new (); 
2446     void *id 
= iter
->user_data
;     
2448     wxGtkTreeModelNode 
*node 
= FindParentNode( iter 
); 
2451         int pos 
= node
->GetChildren().Index( id 
); 
2453         gtk_tree_path_prepend_index( retval
, pos 
); 
2455         id 
= node
->GetItem().GetID(); 
2456         node 
= node
->GetParent(); 
2462 gboolean 
wxDataViewCtrlInternal::iter_next( GtkTreeIter 
*iter 
) 
2464     wxGtkTreeModelNode 
*parent 
= FindParentNode( iter 
); 
2465     if( parent 
== NULL 
) 
2468     int pos 
= parent
->GetChildren().Index( iter
->user_data 
); 
2470     if (pos 
== (int) parent
->GetChildCount()-1) 
2473     iter
->stamp 
= m_gtk_model
->stamp
; 
2474     iter
->user_data 
= parent
->GetChildren().Item( pos
+1 ); 
2479 gboolean 
wxDataViewCtrlInternal::iter_children( GtkTreeIter 
*iter
, GtkTreeIter 
*parent 
) 
2481     wxDataViewItem 
item( (void*) parent
->user_data 
); 
2483     if (!m_wx_model
->IsContainer( item 
)) 
2486     wxGtkTreeModelNode 
*parent_node 
= FindNode( parent 
); 
2487     BuildBranch( parent_node 
); 
2489     if (parent_node
->GetChildCount() == 0) 
2492     iter
->stamp 
= m_gtk_model
->stamp
; 
2493     iter
->user_data 
= (gpointer
) parent_node
->GetChildren().Item( 0 ); 
2498 gboolean 
wxDataViewCtrlInternal::iter_has_child( GtkTreeIter 
*iter 
) 
2500     wxDataViewItem 
item( (void*) iter
->user_data 
); 
2501     bool is_container 
= m_wx_model
->IsContainer( item 
); 
2506     wxGtkTreeModelNode 
*node 
= FindNode( iter 
); 
2507     BuildBranch( node 
); 
2509     return (node
->GetChildCount() > 0); 
2512 gint 
wxDataViewCtrlInternal::iter_n_children( GtkTreeIter 
*iter 
) 
2514     wxDataViewItem 
item( (void*) iter
->user_data 
); 
2516     if (!m_wx_model
->IsContainer( item 
)) 
2519     wxGtkTreeModelNode 
*parent_node 
= FindNode( iter 
); 
2520     BuildBranch( parent_node 
); 
2522     // wxPrintf( "iter_n_children %d\n", parent_node->GetChildCount() ); 
2524     return parent_node
->GetChildCount(); 
2527 gboolean 
wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter 
*iter
, GtkTreeIter 
*parent
, gint n 
) 
2530     if (parent
) id 
= (void*) parent
->user_data
; 
2531     wxDataViewItem 
item( id 
); 
2533     if (!m_wx_model
->IsContainer( item 
)) 
2536     wxGtkTreeModelNode 
*parent_node 
= FindNode( parent 
); 
2537     BuildBranch( parent_node 
); 
2539     // wxPrintf( "iter_nth_child %d\n", n ); 
2541     iter
->stamp 
= m_gtk_model
->stamp
; 
2542     iter
->user_data 
= parent_node
->GetChildren().Item( n 
); 
2547 gboolean 
wxDataViewCtrlInternal::iter_parent( GtkTreeIter 
*iter
, GtkTreeIter 
*child 
) 
2549     wxGtkTreeModelNode 
*node 
= FindParentNode( child 
); 
2553     iter
->stamp 
= m_gtk_model
->stamp
; 
2554     iter
->user_data 
= (gpointer
) node
->GetItem().GetID(); 
2559 static wxGtkTreeModelNode
* 
2560 wxDataViewCtrlInternal_FindNode( wxDataViewModel 
* model
, wxGtkTreeModelNode 
*treeNode
, const wxDataViewItem 
&item 
) 
2566     list
.DeleteContents( true ); 
2567     wxDataViewItem 
it( item 
); 
2570         wxDataViewItem 
* pItem 
= new wxDataViewItem( it 
); 
2571         list
.Insert( pItem 
); 
2572         it 
= model
->GetParent( it 
); 
2575     wxGtkTreeModelNode 
* node 
= treeNode
; 
2576     for( ItemList::compatibility_iterator n 
= list
.GetFirst(); n
; n 
= n
->GetNext() ) 
2578         if( node 
&& node
->GetNodes().GetCount() != 0 ) 
2580             int len 
= node
->GetNodes().GetCount(); 
2581             wxGtkTreeModelNodes nodes 
= node
->GetNodes(); 
2583             for( ; j 
< len
; j 
++) 
2585                 if( nodes
[j
]->GetItem() == *(n
->GetData())) 
2604 wxGtkTreeModelNode 
*wxDataViewCtrlInternal::FindNode( GtkTreeIter 
*iter 
) 
2609     wxDataViewItem 
item( (void*) iter
->user_data 
); 
2613     wxGtkTreeModelNode 
*result 
= wxDataViewCtrlInternal_FindNode( m_wx_model
, m_root
, item 
); 
2617         wxPrintf( "Not found %d\n", (int) iter
->user_data 
); 
2625 wxGtkTreeModelNode 
*wxDataViewCtrlInternal::FindNode( const wxDataViewItem 
&item 
) 
2630     wxGtkTreeModelNode 
*result 
= wxDataViewCtrlInternal_FindNode( m_wx_model
, m_root
, item 
); 
2634         wxPrintf( "Not found %d\n", (int) item
.GetID() ); 
2642 static wxGtkTreeModelNode
* 
2643 wxDataViewCtrlInternal_FindParentNode( wxDataViewModel 
* model
, wxGtkTreeModelNode 
*treeNode
, const wxDataViewItem 
&item 
) 
2649     list
.DeleteContents( true ); 
2653     wxDataViewItem 
it( model
->GetParent( item 
) ); 
2656         wxDataViewItem 
* pItem 
= new wxDataViewItem( it 
); 
2657         list
.Insert( pItem 
); 
2658         it 
= model
->GetParent( it 
); 
2661     wxGtkTreeModelNode 
* node 
= treeNode
; 
2662     for( ItemList::compatibility_iterator n 
= list
.GetFirst(); n
; n 
= n
->GetNext() ) 
2664         if( node 
&& node
->GetNodes().GetCount() != 0 ) 
2666             int len 
= node
->GetNodes().GetCount(); 
2667             wxGtkTreeModelNodes nodes 
= node
->GetNodes(); 
2669             for( ; j 
< len
; j 
++) 
2671                 if( nodes
[j
]->GetItem() == *(n
->GetData())) 
2686     //Examine whether the node is item's parent node 
2687     int len 
= node
->GetChildCount(); 
2688     for( int i 
= 0; i 
< len 
; i 
++ ) 
2690         if( node
->GetChildren().Item( i 
) == item
.GetID() ) 
2696 wxGtkTreeModelNode 
*wxDataViewCtrlInternal::FindParentNode( GtkTreeIter 
*iter 
) 
2701     wxDataViewItem 
item( (void*) iter
->user_data 
); 
2705     return wxDataViewCtrlInternal_FindParentNode( m_wx_model
, m_root
, item 
); 
2708 wxGtkTreeModelNode 
*wxDataViewCtrlInternal::FindParentNode( const wxDataViewItem 
&item 
) 
2713     return wxDataViewCtrlInternal_FindParentNode( m_wx_model
, m_root
, item 
); 
2716 //----------------------------------------------------------------------------- 
2717 // wxDataViewCtrl signal callbacks 
2718 //----------------------------------------------------------------------------- 
2721 wxdataview_selection_changed_callback( GtkTreeSelection
* selection
, wxDataViewCtrl 
*dv 
) 
2723     if (!GTK_WIDGET_REALIZED(dv
->m_widget
)) 
2726     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_SELECTED
, dv
->GetId() ); 
2727     event
.SetItem( dv
->GetSelection() ); 
2728     event
.SetModel( dv
->GetModel() ); 
2729     dv
->GetEventHandler()->ProcessEvent( event 
); 
2733 wxdataview_row_activated_callback( GtkTreeView
* treeview
, GtkTreePath 
*path
, 
2734                                    GtkTreeViewColumn 
*column
, wxDataViewCtrl 
*dv 
) 
2736     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED
, dv
->GetId() ); 
2739     dv
->GtkGetInternal()->get_iter( &iter
, path 
); 
2740     wxDataViewItem 
item( (void*) iter
.user_data 
);; 
2741     event
.SetItem( item 
); 
2742     event
.SetModel( dv
->GetModel() ); 
2743     dv
->GetEventHandler()->ProcessEvent( event 
); 
2747 wxdataview_test_expand_row_callback( GtkTreeView
* treeview
, GtkTreeIter
* iter
, 
2748                                      GtkTreePath 
*path
, wxDataViewCtrl 
*dv 
) 
2750     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING
, dv
->GetId() ); 
2752     wxDataViewItem 
item( (void*) iter
->user_data 
);; 
2753     event
.SetItem( item 
); 
2754     event
.SetModel( dv
->GetModel() ); 
2755     dv
->GetEventHandler()->ProcessEvent( event 
); 
2757     return !event
.IsAllowed(); 
2761 wxdataview_row_expanded_callback( GtkTreeView
* treeview
, GtkTreeIter
* iter
, 
2762                                   GtkTreePath 
*path
, wxDataViewCtrl 
*dv 
) 
2764     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDED
, dv
->GetId() ); 
2766     wxDataViewItem 
item( (void*) iter
->user_data 
);; 
2767     event
.SetItem( item 
); 
2768     event
.SetModel( dv
->GetModel() ); 
2769     dv
->GetEventHandler()->ProcessEvent( event 
); 
2773 wxdataview_test_collapse_row_callback( GtkTreeView
* treeview
, GtkTreeIter
* iter
, 
2774                                        GtkTreePath 
*path
, wxDataViewCtrl 
*dv 
) 
2776     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSING
, dv
->GetId() ); 
2778     wxDataViewItem 
item( (void*) iter
->user_data 
);; 
2779     event
.SetItem( item 
); 
2780     event
.SetModel( dv
->GetModel() ); 
2781     dv
->GetEventHandler()->ProcessEvent( event 
); 
2783     return !event
.IsAllowed(); 
2787 wxdataview_row_collapsed_callback( GtkTreeView
* treeview
, GtkTreeIter
* iter
, 
2788                                    GtkTreePath 
*path
, wxDataViewCtrl 
*dv 
) 
2790     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSED
, dv
->GetId() ); 
2792     wxDataViewItem 
item( (void*) iter
->user_data 
);; 
2793     event
.SetItem( item 
); 
2794     event
.SetModel( dv
->GetModel() ); 
2795     dv
->GetEventHandler()->ProcessEvent( event 
); 
2798 //----------------------------------------------------------------------------- 
2800 //----------------------------------------------------------------------------- 
2802 //----------------------------------------------------------------------------- 
2803 // InsertChild for wxDataViewCtrl 
2804 //----------------------------------------------------------------------------- 
2806 static void wxInsertChildInDataViewCtrl( wxWindowGTK
* parent
, wxWindowGTK
* child 
) 
2808     wxDataViewCtrl 
* dvc 
= (wxDataViewCtrl
*) parent
; 
2809     GtkWidget 
*treeview 
= dvc
->GtkGetTreeView(); 
2811     // Insert widget in GtkTreeView 
2812     if (GTK_WIDGET_REALIZED(treeview
)) 
2813         gtk_widget_set_parent_window( child
->m_widget
, 
2814           gtk_tree_view_get_bin_window( GTK_TREE_VIEW(treeview
) ) ); 
2815     gtk_widget_set_parent( child
->m_widget
, treeview 
); 
2819 void gtk_dataviewctrl_size_callback( GtkWidget 
*WXUNUSED(widget
), 
2820                                      GtkAllocation 
*alloc
, 
2821                                      wxDataViewCtrl 
*win 
) 
2823     wxWindowList::compatibility_iterator node 
= win
->GetChildren().GetFirst(); 
2826         wxWindow 
*child 
= node
->GetData(); 
2829         gtk_widget_size_request( child
->m_widget
, &req 
); 
2831         GtkAllocation alloc
; 
2832         alloc
.x 
= child
->m_x
; 
2833         alloc
.y 
= child
->m_y
; 
2834         alloc
.width 
= child
->m_width
; 
2835         alloc
.height 
= child
->m_height
; 
2836         gtk_widget_size_allocate( child
->m_widget
, &alloc 
); 
2838         node 
= node
->GetNext(); 
2844 IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl
, wxDataViewCtrlBase
) 
2846 wxDataViewCtrl::~wxDataViewCtrl() 
2849         GetModel()->RemoveNotifier( m_notifier 
); 
2851     // remove the model from the GtkTreeView before it gets destroyed by the 
2852     // wxDataViewCtrlBase's dtor 
2853     gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview
), NULL 
); 
2858 void wxDataViewCtrl::Init() 
2863 bool wxDataViewCtrl::Create(wxWindow 
*parent
, wxWindowID id
, 
2864            const wxPoint
& pos
, const wxSize
& size
, 
2865            long style
, const wxValidator
& validator 
) 
2869     if (!PreCreation( parent
, pos
, size 
) || 
2870         !CreateBase( parent
, id
, pos
, size
, style
, validator 
)) 
2872         wxFAIL_MSG( wxT("wxDataViewCtrl creation failed") ); 
2876     m_insertCallback 
= wxInsertChildInDataViewCtrl
; 
2878     m_widget 
= gtk_scrolled_window_new (NULL
, NULL
); 
2880     GtkScrolledWindowSetBorder(m_widget
, style
); 
2882     m_treeview 
= gtk_tree_view_new(); 
2883     gtk_container_add (GTK_CONTAINER (m_widget
), m_treeview
); 
2885     g_signal_connect (m_treeview
, "size_allocate", 
2886                      G_CALLBACK (gtk_dataviewctrl_size_callback
), this); 
2889     if (!gtk_check_version(2,6,0)) 
2890         gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview
), TRUE 
); 
2893     if (style 
& wxDV_MULTIPLE
) 
2895         GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
2896         gtk_tree_selection_set_mode( selection
, GTK_SELECTION_MULTIPLE 
); 
2899     gtk_tree_view_set_headers_visible( GTK_TREE_VIEW(m_treeview
), (style 
& wxDV_NO_HEADER
) == 0 ); 
2902     if (!gtk_check_version(2,10,0)) 
2904         GtkTreeViewGridLines grid 
= GTK_TREE_VIEW_GRID_LINES_NONE
; 
2906         if ((style 
& wxDV_HORIZ_RULES
) != 0 && 
2907             (style 
& wxDV_VERT_RULES
) != 0) 
2908             grid 
= GTK_TREE_VIEW_GRID_LINES_BOTH
; 
2909         else if (style 
& wxDV_VERT_RULES
) 
2910             grid 
= GTK_TREE_VIEW_GRID_LINES_VERTICAL
; 
2911         else if (style 
& wxDV_HORIZ_RULES
) 
2912             grid 
= GTK_TREE_VIEW_GRID_LINES_HORIZONTAL
; 
2914         gtk_tree_view_set_grid_lines( GTK_TREE_VIEW(m_treeview
), grid 
); 
2919         gtk_tree_view_set_rules_hint( GTK_TREE_VIEW(m_treeview
), (style 
& wxDV_HORIZ_RULES
) != 0 ); 
2922     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_widget
), 
2923         GTK_POLICY_AUTOMATIC
, GTK_POLICY_ALWAYS
); 
2924     gtk_widget_show (m_treeview
); 
2926     m_parent
->DoAddChild( this ); 
2930     GtkEnableSelectionEvents(); 
2932     g_signal_connect_after (m_treeview
, "row-activated", 
2933                             G_CALLBACK (wxdataview_row_activated_callback
), this); 
2935     g_signal_connect (m_treeview
, "test-collapse-row", 
2936                             G_CALLBACK (wxdataview_test_collapse_row_callback
), this); 
2938     g_signal_connect_after (m_treeview
, "row-collapsed", 
2939                             G_CALLBACK (wxdataview_row_collapsed_callback
), this); 
2941     g_signal_connect (m_treeview
, "test-expand-row", 
2942                             G_CALLBACK (wxdataview_test_expand_row_callback
), this); 
2944     g_signal_connect_after (m_treeview
, "row-expanded", 
2945                             G_CALLBACK (wxdataview_row_expanded_callback
), this); 
2950 void wxDataViewCtrl::OnInternalIdle() 
2952     wxWindow::OnInternalIdle(); 
2954     unsigned int cols 
= GetColumnCount(); 
2956     for (i 
= 0; i 
< cols
; i
++) 
2958         wxDataViewColumn 
*col 
= GetColumn( i 
); 
2959         col
->OnInternalIdle(); 
2963 bool wxDataViewCtrl::AssociateModel( wxDataViewModel 
*model 
) 
2965     if (!wxDataViewCtrlBase::AssociateModel( model 
)) 
2968     GtkWxTreeModel 
*gtk_model 
= wxgtk_tree_model_new(); 
2969     m_internal 
= new wxDataViewCtrlInternal( this, model
, gtk_model 
); 
2970     gtk_model
->internal 
= m_internal
; 
2972     m_notifier 
= new wxGtkDataViewModelNotifier( gtk_model
, model
, this ); 
2974     model
->AddNotifier( m_notifier 
); 
2976     gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview
), GTK_TREE_MODEL(gtk_model
) ); 
2978     // unref in wxDataViewCtrlInternal 
2979     // g_object_unref( gtk_model ); 
2984 bool wxDataViewCtrl::AppendColumn( wxDataViewColumn 
*col 
) 
2986     if (!wxDataViewCtrlBase::AppendColumn(col
)) 
2989     GtkTreeViewColumn 
*column 
= (GtkTreeViewColumn 
*)col
->GetGtkHandle(); 
2991     gtk_tree_view_append_column( GTK_TREE_VIEW(m_treeview
), column 
); 
2996 wxDataViewItem 
wxDataViewCtrl::GetSelection() const 
2998     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
3000     if (m_windowStyle 
& wxDV_MULTIPLE
) 
3002         // Report the first one 
3003         GtkTreeModel 
*model
; 
3004         GList 
*list 
= gtk_tree_selection_get_selected_rows( selection
, &model 
); 
3008             GtkTreePath 
*path 
= (GtkTreePath
*) list
->data
; 
3010             m_internal
->get_iter( &iter
, path 
); 
3013             g_list_foreach( list
, (GFunc
) gtk_tree_path_free
, NULL 
); 
3014             g_list_free( list 
); 
3016             return wxDataViewItem( (void*) iter
.user_data 
); 
3022         if (gtk_tree_selection_get_selected( selection
, NULL
, &iter 
)) 
3024             wxDataViewItem 
item( (void*) iter
.user_data 
); 
3029     return wxDataViewItem(0); 
3032 int wxDataViewCtrl::GetSelections( wxDataViewItemArray 
& sel 
) const 
3036     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
3037     if (HasFlag(wxDV_MULTIPLE
)) 
3039         GtkTreeModel 
*model
; 
3040         GList 
*list 
= gtk_tree_selection_get_selected_rows( selection
, &model 
); 
3045             GtkTreePath 
*path 
= (GtkTreePath
*) list
->data
; 
3048             m_internal
->get_iter( &iter
, path 
); 
3050             sel
.Add( wxDataViewItem( (void*) iter
.user_data 
) ); 
3052             list 
= g_list_next( list 
); 
3057         g_list_foreach( list
, (GFunc
) gtk_tree_path_free
, NULL 
); 
3058         g_list_free( list 
); 
3064         GtkTreeModel 
*model
; 
3066         gboolean has_selection 
= gtk_tree_selection_get_selected( selection
, &model
, &iter 
); 
3069             sel
.Add( wxDataViewItem( (void*) iter
.user_data
) ); 
3077 void wxDataViewCtrl::SetSelections( const wxDataViewItemArray 
& sel 
) 
3079     GtkDisableSelectionEvents(); 
3081     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
3083     gtk_tree_selection_unselect_all( selection 
); 
3086     for (i 
= 0; i 
< sel
.GetCount(); i
++) 
3089         iter
.user_data 
= (gpointer
) sel
[i
].GetID(); 
3090         gtk_tree_selection_select_iter( selection
, &iter 
); 
3093     GtkEnableSelectionEvents(); 
3096 void wxDataViewCtrl::Select( const wxDataViewItem 
& item 
) 
3098     GtkDisableSelectionEvents(); 
3100     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
3103     iter
.user_data 
= (gpointer
) item
.GetID(); 
3104     gtk_tree_selection_select_iter( selection
, &iter 
); 
3106     GtkEnableSelectionEvents(); 
3109 void wxDataViewCtrl::Unselect( const wxDataViewItem 
& item 
) 
3111     GtkDisableSelectionEvents(); 
3113     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
3116     iter
.user_data 
= (gpointer
) item
.GetID(); 
3117     gtk_tree_selection_unselect_iter( selection
, &iter 
); 
3119     GtkEnableSelectionEvents(); 
3122 bool wxDataViewCtrl::IsSelected( const wxDataViewItem 
& item 
) const 
3124     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
3127     iter
.user_data 
= (gpointer
) item
.GetID(); 
3129     return gtk_tree_selection_iter_is_selected( selection
, &iter 
); 
3132 void wxDataViewCtrl::SelectAll() 
3134     GtkDisableSelectionEvents(); 
3136     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
3138     gtk_tree_selection_select_all( selection 
); 
3140     GtkEnableSelectionEvents(); 
3143 void wxDataViewCtrl::UnselectAll() 
3145     GtkDisableSelectionEvents(); 
3147     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
3149     gtk_tree_selection_unselect_all( selection 
); 
3151     GtkEnableSelectionEvents(); 
3154 void wxDataViewCtrl::EnsureVisible( const wxDataViewItem 
& item
, const wxDataViewColumn 
*column 
) 
3157     iter
.user_data 
= (gpointer
) item
.GetID(); 
3158     GtkTreePath 
*path 
= m_internal
->get_path( &iter 
); 
3159     gtk_tree_view_scroll_to_cell( GTK_TREE_VIEW(m_treeview
), path
, NULL
, false, 0.0, 0.0 ); 
3160     gtk_tree_path_free( path 
); 
3163 void wxDataViewCtrl::HitTest( const wxPoint 
&point
,  
3164                               wxDataViewItem 
&item
,  wxDataViewColumn 
*&column 
) const 
3166     item 
= wxDataViewItem(0); 
3170 wxRect 
wxDataViewCtrl::GetItemRect( const wxDataViewItem 
&item
,  
3171                                     const wxDataViewColumn 
*column 
) const 
3176 void wxDataViewCtrl::DoSetExpanderColumn() 
3178     gtk_tree_view_set_expander_column( GTK_TREE_VIEW(m_treeview
),  
3179         GTK_TREE_VIEW_COLUMN( GetExpanderColumn()->GetGtkHandle() ) ); 
3182 void wxDataViewCtrl::DoSetIndent() 
3186 void wxDataViewCtrl::GtkDisableSelectionEvents() 
3188     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
3189     g_signal_handlers_disconnect_by_func( selection
, 
3190                             (gpointer
) (wxdataview_selection_changed_callback
), this); 
3193 void wxDataViewCtrl::GtkEnableSelectionEvents() 
3195     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
3196     g_signal_connect_after (selection
, "changed", 
3197                             G_CALLBACK (wxdataview_selection_changed_callback
), this); 
3202 wxDataViewCtrl::GetClassDefaultAttributes(wxWindowVariant 
WXUNUSED(variant
)) 
3204     return GetDefaultAttributesFromGTKWidget(gtk_tree_view_new
); 
3209     // !wxUSE_GENERICDATAVIEWCTRL 
3212     // wxUSE_DATAVIEWCTRL