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     GtkTreePath 
*get_path_safe( GtkTreeIter 
*iter
); 
  72     gboolean 
iter_next( GtkTreeIter 
*iter 
); 
  73     gboolean 
iter_children( GtkTreeIter 
*iter
, GtkTreeIter 
*parent
); 
  74     gboolean 
iter_has_child( GtkTreeIter 
*iter 
); 
  75     gint 
iter_n_children( GtkTreeIter 
*iter 
); 
  76     gboolean 
iter_nth_child( GtkTreeIter 
*iter
, GtkTreeIter 
*parent
, gint n 
); 
  77     gboolean 
iter_parent( GtkTreeIter 
*iter
, GtkTreeIter 
*child 
); 
  79     wxDataViewModel
* GetDataViewModel() { return m_wx_model
; } 
  80     wxDataViewCtrl
* GetOwner()          { return m_owner
; } 
  81     GtkWxTreeModel
* GetGtkModel()       { return m_gtk_model
; } 
  83     bool ItemAdded( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
); 
  84     bool ItemDeleted( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
); 
  85     bool ItemChanged( const wxDataViewItem 
&item 
); 
  86     bool ValueChanged( const wxDataViewItem 
&item
, unsigned int col 
); 
  90     void SetSortOrder( GtkSortType sort_order 
) { m_sort_order 
= sort_order
; } 
  91     GtkSortType 
GetSortOrder()                  { return m_sort_order
; } 
  93     void SetSortColumn( unsigned int column 
)   { m_sort_column 
= column
; } 
  94     unsigned int GetSortColumn()                { return m_sort_column
; } 
  98     wxGtkTreeModelNode 
*FindNode( const wxDataViewItem 
&item 
); 
  99     wxGtkTreeModelNode 
*FindNode( GtkTreeIter 
*iter 
); 
 100     wxGtkTreeModelNode 
*FindParentNode( const wxDataViewItem 
&item 
); 
 101     wxGtkTreeModelNode 
*FindParentNode( GtkTreeIter 
*iter 
); 
 102     void BuildBranch( wxGtkTreeModelNode 
*branch 
); 
 105     wxGtkTreeModelNode   
*m_root
; 
 106     wxDataViewModel      
*m_wx_model
; 
 107     GtkWxTreeModel       
*m_gtk_model
; 
 108     wxDataViewCtrl       
*m_owner
; 
 109     GtkSortType           m_sort_order
; 
 110     unsigned int          m_sort_column
; 
 114 //----------------------------------------------------------------------------- 
 115 // wxGtkTreeModelNode 
 116 //----------------------------------------------------------------------------- 
 118 int LINKAGEMODE 
wxGtkTreeModelNodeCmp( void *id1
, void *id2 
); 
 120 WX_DEFINE_ARRAY_PTR( wxGtkTreeModelNode
*, wxGtkTreeModelNodes 
); 
 121 WX_DEFINE_SORTED_ARRAY( void* , wxGtkTreeModelChildren 
); 
 123 class wxGtkTreeModelNode
 
 126     wxGtkTreeModelNode( wxGtkTreeModelNode
* parent
, const wxDataViewItem 
&item
, 
 127       wxDataViewCtrlInternal 
*internal 
) 
 131         m_internal 
= internal
; 
 132         g_internal 
= internal
; 
 133         m_children 
= new wxGtkTreeModelChildren( wxGtkTreeModelNodeCmp 
); 
 136     ~wxGtkTreeModelNode() 
 138         g_internal 
= m_internal
; 
 139         size_t count 
= m_children
->GetCount(); 
 141         for (i 
= 0; i 
< count
; i
++) 
 143             wxGtkTreeModelNode 
*child 
= m_nodes
.Item( i 
); 
 149     unsigned int AddNode( wxGtkTreeModelNode
* child 
)  
 151             g_internal 
= m_internal
; 
 152             m_nodes
.Add( child 
); 
 153             return m_children
->Add( child
->GetItem().GetID() ); 
 156     unsigned int AddLeave( void* id 
) 
 158             g_internal 
= m_internal
; 
 159             return m_children
->Add( id 
); 
 162     void DeleteChild( void* id 
) 
 164             g_internal 
= m_internal
; 
 166             size_t count 
= m_children
->GetCount(); 
 167             for (pos 
= 0; pos 
< count
; pos
++) 
 169                 if (m_children
->Item( pos 
) == id
) 
 171                     m_children
->RemoveAt( pos 
); 
 175             count 
= m_nodes
.GetCount(); 
 176             for (pos 
= 0; pos 
< count
; pos
++) 
 178                 wxGtkTreeModelNode 
*node 
= m_nodes
.Item( pos 
); 
 179                 if (node
->GetItem().GetID() == id
) 
 181                     m_nodes
.RemoveAt( pos 
); 
 189     wxGtkTreeModelNode
* GetParent()  
 191     wxGtkTreeModelNodes 
&GetNodes()  
 193     wxGtkTreeModelChildren 
&GetChildren()  
 194         { return *m_children
; } 
 196     unsigned int GetChildCount() { return m_children
->GetCount(); } 
 197     unsigned int GetNodesCount() { return m_nodes
.GetCount(); } 
 199     wxDataViewItem 
&GetItem() { return m_item
; } 
 200     wxDataViewCtrlInternal 
*GetInternal() { return m_internal
; } 
 205     wxGtkTreeModelNode         
*m_parent
; 
 206     wxGtkTreeModelNodes         m_nodes
; 
 207     wxGtkTreeModelChildren     
*m_children
; 
 208     wxDataViewItem              m_item
;  
 209     wxDataViewCtrlInternal     
*m_internal
; 
 213 int LINKAGEMODE 
wxGtkTreeModelNodeCmp( void* id1
, void* id2 
) 
 215     int ret 
= g_internal
->GetDataViewModel()->Compare( id1
, id2
,  
 216         g_internal
->GetSortColumn(), (g_internal
->GetSortOrder() == GTK_SORT_ASCENDING
) ); 
 221 //----------------------------------------------------------------------------- 
 223 //----------------------------------------------------------------------------- 
 225 extern bool   g_blockEventsOnDrag
; 
 227 //----------------------------------------------------------------------------- 
 228 // define new GTK+ class wxGtkTreeModel 
 229 //----------------------------------------------------------------------------- 
 233 #define GTK_TYPE_WX_TREE_MODEL               (gtk_wx_tree_model_get_type ()) 
 234 #define GTK_WX_TREE_MODEL(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModel)) 
 235 #define GTK_WX_TREE_MODEL_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModelClass)) 
 236 #define GTK_IS_WX_TREE_MODEL(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_TREE_MODEL)) 
 237 #define GTK_IS_WX_TREE_MODEL_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_TREE_MODEL)) 
 238 #define GTK_WX_TREE_MODEL_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModelClass)) 
 240 GType         
gtk_wx_tree_model_get_type         (void); 
 242 typedef struct _GtkWxTreeModelClass  GtkWxTreeModelClass
; 
 244 struct _GtkWxTreeModel
 
 250   wxDataViewCtrlInternal 
*internal
; 
 253 struct _GtkWxTreeModelClass
 
 255   GObjectClass list_parent_class
; 
 258 static GtkWxTreeModel 
*wxgtk_tree_model_new          (void); 
 259 static void         wxgtk_tree_model_init            (GtkWxTreeModel       
*tree_model
); 
 260 static void         wxgtk_tree_model_class_init      (GtkWxTreeModelClass  
*klass
); 
 261 static void         wxgtk_tree_model_tree_model_init (GtkTreeModelIface    
*iface
); 
 262 static void         wxgtk_tree_model_sortable_init   (GtkTreeSortableIface 
*iface
); 
 263 static void         wxgtk_tree_model_finalize        (GObject           
*object
); 
 264 static GtkTreeModelFlags 
wxgtk_tree_model_get_flags  (GtkTreeModel      
*tree_model
); 
 265 static gint         
wxgtk_tree_model_get_n_columns   (GtkTreeModel      
*tree_model
); 
 266 static GType        
wxgtk_tree_model_get_column_type (GtkTreeModel      
*tree_model
, 
 268 static gboolean     
wxgtk_tree_model_get_iter        (GtkTreeModel      
*tree_model
, 
 271 static GtkTreePath 
*wxgtk_tree_model_get_path        (GtkTreeModel      
*tree_model
, 
 273 static GtkTreePath 
*wxgtk_tree_model_get_path_safe   (GtkTreeModel      
*tree_model
, 
 275 static void         wxgtk_tree_model_get_value       (GtkTreeModel      
*tree_model
, 
 279 static gboolean     
wxgtk_tree_model_iter_next       (GtkTreeModel      
*tree_model
, 
 281 static gboolean     
wxgtk_tree_model_iter_children   (GtkTreeModel      
*tree_model
, 
 283                                                       GtkTreeIter       
*parent
); 
 284 static gboolean     
wxgtk_tree_model_iter_has_child  (GtkTreeModel      
*tree_model
, 
 286 static gint         
wxgtk_tree_model_iter_n_children (GtkTreeModel      
*tree_model
, 
 288 static gboolean     
wxgtk_tree_model_iter_nth_child  (GtkTreeModel      
*tree_model
, 
 292 static gboolean     
wxgtk_tree_model_iter_parent     (GtkTreeModel      
*tree_model
, 
 297 static gboolean 
wxgtk_tree_model_get_sort_column_id    (GtkTreeSortable       
*sortable
, 
 298                                                       gint                     
*sort_column_id
, 
 300 static void     wxgtk_tree_model_set_sort_column_id    (GtkTreeSortable       
*sortable
, 
 303 static void     wxgtk_tree_model_set_sort_func         (GtkTreeSortable       
*sortable
, 
 305                                                       GtkTreeIterCompareFunc    func
, 
 307                                                       GtkDestroyNotify          destroy
); 
 308 static void     wxgtk_tree_model_set_default_sort_func (GtkTreeSortable       
*sortable
, 
 309                                                       GtkTreeIterCompareFunc    func
, 
 311                                                       GtkDestroyNotify          destroy
); 
 312 static gboolean 
wxgtk_tree_model_has_default_sort_func (GtkTreeSortable       
*sortable
); 
 316 static GObjectClass 
*list_parent_class 
= NULL
; 
 319 gtk_wx_tree_model_get_type (void) 
 321     static GType tree_model_type 
= 0; 
 323     if (!tree_model_type
) 
 325         const GTypeInfo tree_model_info 
= 
 327             sizeof (GtkWxTreeModelClass
), 
 328             NULL
,   /* base_init */ 
 329             NULL
,   /* base_finalize */ 
 330             (GClassInitFunc
) wxgtk_tree_model_class_init
, 
 331             NULL
,   /* class_finalize */ 
 332             NULL
,   /* class_data */ 
 333             sizeof (GtkWxTreeModel
), 
 335             (GInstanceInitFunc
) wxgtk_tree_model_init
, 
 338         static const GInterfaceInfo tree_model_iface_info 
= 
 340             (GInterfaceInitFunc
) wxgtk_tree_model_tree_model_init
, 
 345         static const GInterfaceInfo sortable_iface_info 
= 
 347             (GInterfaceInitFunc
) wxgtk_tree_model_sortable_init
, 
 352         tree_model_type 
= g_type_register_static (G_TYPE_OBJECT
, "GtkWxTreeModel", 
 353                                                 &tree_model_info
, (GTypeFlags
)0 ); 
 355         g_type_add_interface_static (tree_model_type
, 
 357                                      &tree_model_iface_info
); 
 358         g_type_add_interface_static (tree_model_type
, 
 359                                      GTK_TYPE_TREE_SORTABLE
, 
 360                                      &sortable_iface_info
); 
 363     return tree_model_type
; 
 366 static GtkWxTreeModel 
* 
 367 wxgtk_tree_model_new(void) 
 369     GtkWxTreeModel 
*retval 
= (GtkWxTreeModel 
*) g_object_new (GTK_TYPE_WX_TREE_MODEL
, NULL
); 
 374 wxgtk_tree_model_class_init (GtkWxTreeModelClass 
*klass
) 
 376     list_parent_class 
= (GObjectClass
*) g_type_class_peek_parent (klass
); 
 377     GObjectClass 
*object_class 
= (GObjectClass
*) klass
; 
 378     object_class
->finalize 
= wxgtk_tree_model_finalize
; 
 382 wxgtk_tree_model_tree_model_init (GtkTreeModelIface 
*iface
) 
 384     iface
->get_flags 
= wxgtk_tree_model_get_flags
; 
 385     iface
->get_n_columns 
= wxgtk_tree_model_get_n_columns
; 
 386     iface
->get_column_type 
= wxgtk_tree_model_get_column_type
; 
 387     iface
->get_iter 
= wxgtk_tree_model_get_iter
; 
 388     iface
->get_path 
= wxgtk_tree_model_get_path
; 
 389     iface
->get_value 
= wxgtk_tree_model_get_value
; 
 390     iface
->iter_next 
= wxgtk_tree_model_iter_next
; 
 391     iface
->iter_children 
= wxgtk_tree_model_iter_children
; 
 392     iface
->iter_has_child 
= wxgtk_tree_model_iter_has_child
; 
 393     iface
->iter_n_children 
= wxgtk_tree_model_iter_n_children
; 
 394     iface
->iter_nth_child 
= wxgtk_tree_model_iter_nth_child
; 
 395     iface
->iter_parent 
= wxgtk_tree_model_iter_parent
; 
 399 wxgtk_tree_model_sortable_init (GtkTreeSortableIface 
*iface
) 
 401     iface
->get_sort_column_id 
= wxgtk_tree_model_get_sort_column_id
; 
 402     iface
->set_sort_column_id 
= wxgtk_tree_model_set_sort_column_id
; 
 403     iface
->set_sort_func 
= wxgtk_tree_model_set_sort_func
; 
 404     iface
->set_default_sort_func 
= wxgtk_tree_model_set_default_sort_func
; 
 405     iface
->has_default_sort_func 
= wxgtk_tree_model_has_default_sort_func
; 
 409 wxgtk_tree_model_init (GtkWxTreeModel 
*tree_model
) 
 411     tree_model
->internal 
= NULL
; 
 412     tree_model
->stamp 
= g_random_int(); 
 416 wxgtk_tree_model_finalize (GObject 
*object
) 
 419     (* list_parent_class
->finalize
) (object
); 
 424 //----------------------------------------------------------------------------- 
 425 // implement callbacks from wxGtkTreeModel class by letting 
 426 // them call the methods of wxWidgets' wxDataViewModel 
 427 //----------------------------------------------------------------------------- 
 429 static GtkTreeModelFlags
 
 430 wxgtk_tree_model_get_flags (GtkTreeModel 
*tree_model
) 
 432     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (tree_model
), (GtkTreeModelFlags
)0 ); 
 434     return GTK_TREE_MODEL_ITERS_PERSIST
; 
 438 wxgtk_tree_model_get_n_columns (GtkTreeModel 
*tree_model
) 
 440     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 441     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), 0); 
 443     return wxtree_model
->internal
->GetDataViewModel()->GetColumnCount(); 
 447 wxgtk_tree_model_get_column_type (GtkTreeModel 
*tree_model
, 
 450     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 451     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), G_TYPE_INVALID
); 
 453     GType gtype 
= G_TYPE_INVALID
; 
 455     wxString wxtype 
= wxtree_model
->internal
->GetDataViewModel()->GetColumnType( (unsigned int) index 
); 
 457     if (wxtype 
== wxT("string")) 
 458         gtype 
= G_TYPE_STRING
; 
 461         wxFAIL_MSG( _T("non-string columns not supported yet") ); 
 468 wxgtk_tree_model_get_iter (GtkTreeModel 
*tree_model
, 
 472     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 473     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 474     g_return_val_if_fail (gtk_tree_path_get_depth (path
) > 0, FALSE
); 
 476     return wxtree_model
->internal
->get_iter( iter
, path 
); 
 480 wxgtk_tree_model_get_path (GtkTreeModel 
*tree_model
, 
 483     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 484     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), NULL
); 
 485     g_return_val_if_fail (iter
->stamp 
== GTK_WX_TREE_MODEL (wxtree_model
)->stamp
, NULL
); 
 487     return wxtree_model
->internal
->get_path( iter 
); 
 491 wxgtk_tree_model_get_path_safe (GtkTreeModel 
*tree_model
, 
 494     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 495     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), NULL
); 
 496     g_return_val_if_fail (iter
->stamp 
== GTK_WX_TREE_MODEL (wxtree_model
)->stamp
, NULL
); 
 498     return wxtree_model
->internal
->get_path_safe( iter 
); 
 502 wxgtk_tree_model_get_value (GtkTreeModel 
*tree_model
, 
 507     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 508     g_return_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
) ); 
 510     wxDataViewModel 
*model 
= wxtree_model
->internal
->GetDataViewModel(); 
 511     wxString mtype 
= model
->GetColumnType( (unsigned int) column 
); 
 512     if (mtype 
== wxT("string")) 
 515         g_value_init( value
, G_TYPE_STRING 
); 
 516         wxDataViewItem 
item( (void*) iter
->user_data 
); 
 517         model
->GetValue( variant
, item
, (unsigned int) column 
); 
 519         g_value_set_string( value
, variant
.GetString().utf8_str() ); 
 523         wxFAIL_MSG( _T("non-string columns not supported yet") ); 
 528 wxgtk_tree_model_iter_next (GtkTreeModel  
*tree_model
, 
 531     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 532     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 533     g_return_val_if_fail (wxtree_model
->stamp 
== iter
->stamp
, FALSE
); 
 535     return wxtree_model
->internal
->iter_next( iter 
); 
 539 wxgtk_tree_model_iter_children (GtkTreeModel 
*tree_model
, 
 543     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 544     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 545     g_return_val_if_fail (wxtree_model
->stamp 
== parent
->stamp
, FALSE
); 
 547     return wxtree_model
->internal
->iter_children( iter
, parent 
); 
 551 wxgtk_tree_model_iter_has_child (GtkTreeModel 
*tree_model
, 
 554     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 555     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 556     g_return_val_if_fail (wxtree_model
->stamp 
== iter
->stamp
, FALSE
); 
 558     return wxtree_model
->internal
->iter_has_child( iter 
); 
 562 wxgtk_tree_model_iter_n_children (GtkTreeModel 
*tree_model
, 
 565     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 566     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 567     g_return_val_if_fail (wxtree_model
->stamp 
== iter
->stamp
, 0); 
 569     return wxtree_model
->internal
->iter_n_children( iter 
); 
 573 wxgtk_tree_model_iter_nth_child (GtkTreeModel 
*tree_model
, 
 578     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 579     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 581     return wxtree_model
->internal
->iter_nth_child( iter
, parent
, n 
); 
 585 wxgtk_tree_model_iter_parent (GtkTreeModel 
*tree_model
, 
 589     GtkWxTreeModel 
*wxtree_model 
= (GtkWxTreeModel 
*) tree_model
; 
 590     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
); 
 591     g_return_val_if_fail (wxtree_model
->stamp 
== child
->stamp
, FALSE
); 
 593     return wxtree_model
->internal
->iter_parent( iter
, child 
); 
 597 gboolean 
wxgtk_tree_model_get_sort_column_id    (GtkTreeSortable        
*sortable
, 
 598                                                       gint                     
*sort_column_id
, 
 601     GtkWxTreeModel 
*tree_model 
= (GtkWxTreeModel 
*) sortable
; 
 603     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (sortable
), FALSE
); 
 606         *sort_column_id 
= tree_model
->internal
->GetSortColumn(); 
 609         *order 
= tree_model
->internal
->GetSortOrder(); 
 614 void     wxgtk_tree_model_set_sort_column_id  (GtkTreeSortable        
*sortable
, 
 618     GtkWxTreeModel 
*tree_model 
= (GtkWxTreeModel 
*) sortable
; 
 619     g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable
) ); 
 621     if ((sort_column_id 
== (gint
) tree_model
->internal
->GetSortColumn()) && 
 622         (order 
== tree_model
->internal
->GetSortOrder())) 
 625     tree_model
->internal
->SetSortColumn( sort_column_id 
); 
 627     tree_model
->internal
->SetSortOrder( order 
); 
 629     gtk_tree_sortable_sort_column_changed (sortable
); 
 631     tree_model
->internal
->GetDataViewModel()->Resort(); 
 633     wxDataViewCtrl 
*dv 
= tree_model
->internal
->GetOwner();     
 634     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED
, dv
->GetId() ); 
 635     // TODO event.SetDataViewColumn( column ); 
 636     event
.SetModel( dv
->GetModel() ); 
 637     dv
->GetEventHandler()->ProcessEvent( event 
); 
 640 void     wxgtk_tree_model_set_sort_func         (GtkTreeSortable        
*sortable
, 
 642                                                       GtkTreeIterCompareFunc    func
, 
 644                                                       GtkDestroyNotify          destroy
) 
 646     g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable
) ); 
 647     g_return_if_fail (func 
!= NULL
); 
 650 void     wxgtk_tree_model_set_default_sort_func (GtkTreeSortable        
*sortable
, 
 651                                                       GtkTreeIterCompareFunc    func
, 
 653                                                       GtkDestroyNotify          destroy
) 
 655     g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable
) ); 
 656     g_return_if_fail (func 
!= NULL
); 
 658     wxPrintf( "wxgtk_tree_model_set_default_sort_func\n" ); 
 661 gboolean 
wxgtk_tree_model_has_default_sort_func (GtkTreeSortable        
*sortable
) 
 666 //----------------------------------------------------------------------------- 
 667 // define new GTK+ class wxGtkRendererRenderer 
 668 //----------------------------------------------------------------------------- 
 672 #define GTK_TYPE_WX_CELL_RENDERER               (gtk_wx_cell_renderer_get_type ()) 
 673 #define GTK_WX_CELL_RENDERER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRenderer)) 
 674 #define GTK_WX_CELL_RENDERER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRendererClass)) 
 675 #define GTK_IS_WX_CELL_RENDERER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_CELL_RENDERER)) 
 676 #define GTK_IS_WX_CELL_RENDERER_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_CELL_RENDERER)) 
 677 #define GTK_WX_CELL_RENDERER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRendererClass)) 
 679 GType            
gtk_wx_cell_renderer_get_type (void); 
 681 typedef struct _GtkWxCellRenderer GtkWxCellRenderer
; 
 682 typedef struct _GtkWxCellRendererClass GtkWxCellRendererClass
; 
 684 struct _GtkWxCellRenderer
 
 686   GtkCellRenderer parent
; 
 689   wxDataViewCustomRenderer 
*cell
; 
 693 struct _GtkWxCellRendererClass
 
 695   GtkCellRendererClass cell_parent_class
; 
 699 static GtkCellRenderer 
*gtk_wx_cell_renderer_new   (void); 
 700 static void gtk_wx_cell_renderer_init ( 
 701                         GtkWxCellRenderer      
*cell 
); 
 702 static void gtk_wx_cell_renderer_class_init( 
 703                         GtkWxCellRendererClass 
*klass 
); 
 704 static void gtk_wx_cell_renderer_finalize ( 
 706 static void gtk_wx_cell_renderer_get_size ( 
 707                         GtkCellRenderer         
*cell
, 
 709                         GdkRectangle            
*rectangle
, 
 714 static void gtk_wx_cell_renderer_render ( 
 715                         GtkCellRenderer         
*cell
, 
 718                         GdkRectangle            
*background_area
, 
 719                         GdkRectangle            
*cell_area
, 
 720                         GdkRectangle            
*expose_area
, 
 721                         GtkCellRendererState     flags 
); 
 722 static gboolean 
gtk_wx_cell_renderer_activate( 
 723                         GtkCellRenderer         
*cell
, 
 727                         GdkRectangle            
*background_area
, 
 728                         GdkRectangle            
*cell_area
, 
 729                         GtkCellRendererState     flags 
); 
 730 static GtkCellEditable 
*gtk_wx_cell_renderer_start_editing( 
 731                         GtkCellRenderer         
*cell
, 
 735                         GdkRectangle            
*background_area
, 
 736                         GdkRectangle            
*cell_area
, 
 737                         GtkCellRendererState     flags 
); 
 740 static GObjectClass 
*cell_parent_class 
= NULL
; 
 745 gtk_wx_cell_renderer_get_type (void) 
 747     static GType cell_wx_type 
= 0; 
 751         const GTypeInfo cell_wx_info 
= 
 753             sizeof (GtkWxCellRendererClass
), 
 754             NULL
, /* base_init */ 
 755             NULL
, /* base_finalize */ 
 756             (GClassInitFunc
) gtk_wx_cell_renderer_class_init
, 
 757             NULL
, /* class_finalize */ 
 758             NULL
, /* class_data */ 
 759             sizeof (GtkWxCellRenderer
), 
 761             (GInstanceInitFunc
) gtk_wx_cell_renderer_init
, 
 764         cell_wx_type 
= g_type_register_static( GTK_TYPE_CELL_RENDERER
, 
 765             "GtkWxCellRenderer", &cell_wx_info
, (GTypeFlags
)0 ); 
 772 gtk_wx_cell_renderer_init (GtkWxCellRenderer 
*cell
) 
 775     cell
->last_click 
= 0; 
 779 gtk_wx_cell_renderer_class_init (GtkWxCellRendererClass 
*klass
) 
 781     GObjectClass 
*object_class 
= G_OBJECT_CLASS (klass
); 
 782     GtkCellRendererClass 
*cell_class 
= GTK_CELL_RENDERER_CLASS (klass
); 
 784     cell_parent_class 
= (GObjectClass
*) g_type_class_peek_parent (klass
); 
 786     object_class
->finalize 
= gtk_wx_cell_renderer_finalize
; 
 788     cell_class
->get_size 
= gtk_wx_cell_renderer_get_size
; 
 789     cell_class
->render 
= gtk_wx_cell_renderer_render
; 
 790     cell_class
->activate 
= gtk_wx_cell_renderer_activate
; 
 791     cell_class
->start_editing 
= gtk_wx_cell_renderer_start_editing
; 
 795 gtk_wx_cell_renderer_finalize (GObject 
*object
) 
 798     (* G_OBJECT_CLASS (cell_parent_class
)->finalize
) (object
); 
 802 gtk_wx_cell_renderer_new (void) 
 804     return (GtkCellRenderer
*) g_object_new (GTK_TYPE_WX_CELL_RENDERER
, NULL
); 
 809 static GtkCellEditable 
*gtk_wx_cell_renderer_start_editing( 
 810                         GtkCellRenderer         
*renderer
, 
 814                         GdkRectangle            
*background_area
, 
 815                         GdkRectangle            
*cell_area
, 
 816                         GtkCellRendererState     flags 
) 
 818     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
 819     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
 820     if (!cell
->HasEditorCtrl()) 
 824     gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
, 
 830     rect
.x 
+= cell_area
->x
; 
 831     rect
.y 
+= cell_area
->y
; 
 832 //    rect.width  -= renderer->xpad * 2; 
 833 //    rect.height -= renderer->ypad * 2; 
 835 //    wxRect renderrect( rect.x, rect.y, rect.width, rect.height ); 
 836     wxRect 
renderrect( cell_area
->x
, cell_area
->y
, cell_area
->width
, cell_area
->height 
); 
 838     GtkTreePath 
*treepath 
= gtk_tree_path_new_from_string( path 
); 
 840     cell
->GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter
, treepath 
); 
 841     wxDataViewItem 
item( (void*) iter
.user_data 
); 
 842     gtk_tree_path_free( treepath 
); 
 844     cell
->StartEditing( item
, renderrect 
); 
 850 gtk_wx_cell_renderer_get_size (GtkCellRenderer 
*renderer
, 
 852                                GdkRectangle    
*cell_area
, 
 858     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
 859     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
 861     wxSize size 
= cell
->GetSize(); 
 863     gint calc_width  
= (gint
) renderer
->xpad 
* 2 + size
.x
; 
 864     gint calc_height 
= (gint
) renderer
->ypad 
* 2 + size
.y
; 
 871     if (cell_area 
&& size
.x 
> 0 && size
.y 
> 0) 
 875             *x_offset 
= (gint
)((renderer
->xalign 
* 
 876                                (cell_area
->width 
- calc_width 
- 2 * renderer
->xpad
))); 
 877             *x_offset 
= MAX (*x_offset
, 0) + renderer
->xpad
; 
 881             *y_offset 
= (gint
)((renderer
->yalign 
* 
 882                                (cell_area
->height 
- calc_height 
- 2 * renderer
->ypad
))); 
 883             *y_offset 
= MAX (*y_offset
, 0) + renderer
->ypad
; 
 891         *height 
= calc_height
; 
 895 gtk_wx_cell_renderer_render (GtkCellRenderer      
*renderer
, 
 898                              GdkRectangle         
*background_area
, 
 899                              GdkRectangle         
*cell_area
, 
 900                              GdkRectangle         
*expose_area
, 
 901                              GtkCellRendererState  flags
) 
 904     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
 905     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
 908     gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
, 
 914     rect
.x 
+= cell_area
->x
; 
 915     rect
.y 
+= cell_area
->y
; 
 916     rect
.width  
-= renderer
->xpad 
* 2; 
 917     rect
.height 
-= renderer
->ypad 
* 2; 
 920     if (gdk_rectangle_intersect (expose_area
, &rect
, &dummy
)) 
 922         wxRect 
renderrect( rect
.x
, rect
.y
, rect
.width
, rect
.height 
); 
 923         wxWindowDC
* dc 
= (wxWindowDC
*) cell
->GetDC(); 
 924         if (dc
->m_window 
== NULL
) 
 926             dc
->m_window 
= window
; 
 931         if (flags 
& GTK_CELL_RENDERER_SELECTED
) 
 932             state 
|= wxDATAVIEW_CELL_SELECTED
; 
 933         if (flags 
& GTK_CELL_RENDERER_PRELIT
) 
 934             state 
|= wxDATAVIEW_CELL_PRELIT
; 
 935         if (flags 
& GTK_CELL_RENDERER_INSENSITIVE
) 
 936             state 
|= wxDATAVIEW_CELL_INSENSITIVE
; 
 937         if (flags 
& GTK_CELL_RENDERER_INSENSITIVE
) 
 938             state 
|= wxDATAVIEW_CELL_INSENSITIVE
; 
 939         if (flags 
& GTK_CELL_RENDERER_FOCUSED
) 
 940             state 
|= wxDATAVIEW_CELL_FOCUSED
; 
 941         cell
->Render( renderrect
, dc
, state 
); 
 946 gtk_wx_cell_renderer_activate( 
 947                         GtkCellRenderer         
*renderer
, 
 951                         GdkRectangle            
*background_area
, 
 952                         GdkRectangle            
*cell_area
, 
 953                         GtkCellRendererState     flags 
) 
 955     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
 956     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
 959     gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
, 
 965     rect
.x 
+= cell_area
->x
; 
 966     rect
.y 
+= cell_area
->y
; 
 967     rect
.width  
-= renderer
->xpad 
* 2; 
 968     rect
.height 
-= renderer
->ypad 
* 2; 
 970     wxRect 
renderrect( rect
.x
, rect
.y
, rect
.width
, rect
.height 
); 
 972     wxDataViewModel 
*model 
= cell
->GetOwner()->GetOwner()->GetModel(); 
 974     GtkTreePath 
*treepath 
= gtk_tree_path_new_from_string( path 
); 
 977     gtk_tree_path_free( treepath 
); 
 979     unsigned int model_col 
= cell
->GetOwner()->GetModelColumn(); 
 985         // activated by <ENTER> 
 986         if (cell
->Activate( renderrect
, model
, item
, model_col 
)) 
 991     else if (event
->type 
== GDK_BUTTON_PRESS
) 
 993         GdkEventButton 
*button_event 
= (GdkEventButton
*) event
; 
 994         wxPoint 
pt( ((int) button_event
->x
) - renderrect
.x
, 
 995                     ((int) button_event
->y
) - renderrect
.y 
); 
 998         if (button_event
->button 
== 1) 
1000             if (cell
->LeftClick( pt
, renderrect
, model
, item
, model_col 
)) 
1002             // TODO: query system double-click time 
1003             if (button_event
->time 
- wxrenderer
->last_click 
< 400) 
1004                 if (cell
->Activate( renderrect
, model
, item
, model_col 
)) 
1007         if (button_event
->button 
== 3) 
1009             if (cell
->RightClick( pt
, renderrect
, model
, item
, model_col 
)) 
1013         wxrenderer
->last_click 
= button_event
->time
; 
1021 // --------------------------------------------------------- 
1022 // wxGtkDataViewModelNotifier 
1023 // --------------------------------------------------------- 
1025 class wxGtkDataViewModelNotifier
: public wxDataViewModelNotifier
 
1028     wxGtkDataViewModelNotifier( GtkWxTreeModel  
*wxgtk_model
, 
1029                                 wxDataViewModel 
*wx_model
, 
1030                                 wxDataViewCtrl  
*ctrl 
); 
1031     ~wxGtkDataViewModelNotifier(); 
1033     virtual bool ItemAdded( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
); 
1034     virtual bool ItemDeleted( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
); 
1035     virtual bool ItemChanged( const wxDataViewItem 
&item 
); 
1036     virtual bool ValueChanged( const wxDataViewItem 
&item
, unsigned int col 
); 
1037     virtual bool Cleared(); 
1038     virtual void Resort(); 
1040     GtkWxTreeModel      
*m_wxgtk_model
; 
1041     wxDataViewModel     
*m_wx_model
; 
1042     wxDataViewCtrl      
*m_owner
; 
1045 // --------------------------------------------------------- 
1046 // wxGtkDataViewListModelNotifier 
1047 // --------------------------------------------------------- 
1049 wxGtkDataViewModelNotifier::wxGtkDataViewModelNotifier( 
1050     GtkWxTreeModel
* wxgtk_model
, wxDataViewModel 
*wx_model
, 
1051     wxDataViewCtrl 
*ctrl 
) 
1053     m_wxgtk_model 
= wxgtk_model
; 
1054     m_wx_model 
= wx_model
; 
1058 wxGtkDataViewModelNotifier::~wxGtkDataViewModelNotifier() 
1061     m_wxgtk_model 
= NULL
; 
1064 bool wxGtkDataViewModelNotifier::ItemAdded( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
) 
1066     m_owner
->GtkGetInternal()->ItemAdded( parent
, item 
); 
1069     iter
.stamp 
= m_wxgtk_model
->stamp
; 
1070     iter
.user_data 
= (gpointer
) item
.GetID(); 
1072     GtkTreePath 
*path 
= wxgtk_tree_model_get_path(  
1073         GTK_TREE_MODEL(m_wxgtk_model
), &iter 
); 
1074     gtk_tree_model_row_inserted(  
1075         GTK_TREE_MODEL(m_wxgtk_model
), path
, &iter
); 
1076     gtk_tree_path_free (path
); 
1081 bool wxGtkDataViewModelNotifier::ItemDeleted( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
) 
1084     iter
.stamp 
= m_wxgtk_model
->stamp
; 
1085     iter
.user_data 
= (gpointer
) item
.GetID(); 
1087     GtkTreePath 
*path 
= wxgtk_tree_model_get_path_safe(  
1088         GTK_TREE_MODEL(m_wxgtk_model
), &iter 
); 
1089     gtk_tree_model_row_deleted( 
1090         GTK_TREE_MODEL(m_wxgtk_model
), path 
); 
1091     gtk_tree_path_free (path
); 
1093     m_owner
->GtkGetInternal()->ItemDeleted( parent
, item 
); 
1098 void wxGtkDataViewModelNotifier::Resort() 
1100     m_owner
->GtkGetInternal()->Resort(); 
1103 bool wxGtkDataViewModelNotifier::ItemChanged( const wxDataViewItem 
&item 
) 
1106     iter
.stamp 
= m_wxgtk_model
->stamp
; 
1107     iter
.user_data 
= (gpointer
) item
.GetID(); 
1109     GtkTreePath 
*path 
= wxgtk_tree_model_get_path(  
1110         GTK_TREE_MODEL(m_wxgtk_model
), &iter 
); 
1111     gtk_tree_model_row_changed( 
1112         GTK_TREE_MODEL(m_wxgtk_model
), path
, &iter 
); 
1113     gtk_tree_path_free (path
); 
1115     m_owner
->GtkGetInternal()->ItemChanged( item 
); 
1120 bool wxGtkDataViewModelNotifier::ValueChanged( const wxDataViewItem 
&item
, unsigned int model_col 
) 
1122     // This adds GTK+'s missing MVC logic for ValueChanged 
1124     for (index 
= 0; index 
< m_owner
->GetColumnCount(); index
++) 
1126         wxDataViewColumn 
*column 
= m_owner
->GetColumn( index 
); 
1127         if (column
->GetModelColumn() == model_col
) 
1129             GtkTreeView 
*widget 
= GTK_TREE_VIEW(m_owner
->m_treeview
); 
1130             GtkTreeViewColumn 
*gcolumn 
= GTK_TREE_VIEW_COLUMN(column
->GetGtkHandle()); 
1134             iter
.stamp 
= m_wxgtk_model
->stamp
; 
1135             iter
.user_data 
= (gpointer
) item
.GetID(); 
1136             GtkTreePath 
*path 
= wxgtk_tree_model_get_path(  
1137                 GTK_TREE_MODEL(m_wxgtk_model
), &iter 
); 
1138             GdkRectangle cell_area
; 
1139             gtk_tree_view_get_cell_area( widget
, path
, gcolumn
, &cell_area 
); 
1140             gtk_tree_path_free( path 
); 
1142             GtkAdjustment
* hadjust 
= gtk_tree_view_get_hadjustment( widget 
); 
1143             double d 
= gtk_adjustment_get_value( hadjust 
); 
1144             int xdiff 
= (int) d
; 
1146             int ydiff 
= gcolumn
->button
->allocation
.height
; 
1148             gtk_widget_queue_draw_area( GTK_WIDGET(widget
), 
1149                 cell_area
.x 
- xdiff
, ydiff 
+ cell_area
.y
, cell_area
.width
, cell_area
.height 
); 
1151             m_owner
->GtkGetInternal()->ValueChanged( item
, model_col 
); 
1160 bool wxGtkDataViewModelNotifier::Cleared() 
1162     // TODO: delete everything 
1164     m_owner
->GtkGetInternal()->Cleared(); 
1169 // --------------------------------------------------------- 
1170 // wxDataViewRenderer 
1171 // --------------------------------------------------------- 
1173 IMPLEMENT_ABSTRACT_CLASS(wxDataViewRenderer
, wxDataViewRendererBase
) 
1175 wxDataViewRenderer::wxDataViewRenderer( const wxString 
&varianttype
, wxDataViewCellMode mode
, 
1177     wxDataViewRendererBase( varianttype
, mode
, align 
) 
1181     // NOTE: SetMode() and SetAlignment() needs to be called in the renderer's ctor, 
1182     //       after the m_renderer pointer has been initialized 
1185 void wxDataViewRenderer::SetMode( wxDataViewCellMode mode 
) 
1187     GtkCellRendererMode gtkMode
; 
1190     case wxDATAVIEW_CELL_INERT
: 
1191         gtkMode 
= GTK_CELL_RENDERER_MODE_INERT
; 
1193     case wxDATAVIEW_CELL_ACTIVATABLE
: 
1194         gtkMode 
= GTK_CELL_RENDERER_MODE_ACTIVATABLE
; 
1196     case wxDATAVIEW_CELL_EDITABLE
: 
1197         gtkMode 
= GTK_CELL_RENDERER_MODE_EDITABLE
; 
1201     GValue gvalue 
= { 0, }; 
1202     g_value_init( &gvalue
, gtk_cell_renderer_mode_get_type() ); 
1203     g_value_set_enum( &gvalue
, gtkMode 
); 
1204     g_object_set_property( G_OBJECT(m_renderer
), "mode", &gvalue 
); 
1205     g_value_unset( &gvalue 
); 
1208 wxDataViewCellMode 
wxDataViewRenderer::GetMode() const 
1210     wxDataViewCellMode ret
; 
1213     g_object_get( G_OBJECT(m_renderer
), "mode", &gvalue
, NULL
); 
1215     switch (g_value_get_enum(&gvalue
)) 
1217     case GTK_CELL_RENDERER_MODE_INERT
: 
1218         ret 
= wxDATAVIEW_CELL_INERT
; 
1220     case GTK_CELL_RENDERER_MODE_ACTIVATABLE
: 
1221         ret 
= wxDATAVIEW_CELL_ACTIVATABLE
; 
1223     case GTK_CELL_RENDERER_MODE_EDITABLE
: 
1224         ret 
= wxDATAVIEW_CELL_EDITABLE
; 
1228     g_value_unset( &gvalue 
); 
1233 void wxDataViewRenderer::SetAlignment( int align 
) 
1235     // horizontal alignment: 
1237     gfloat xalign 
= 0.0; 
1238     if (align 
& wxALIGN_RIGHT
) 
1240     else if (align 
& wxALIGN_CENTER_HORIZONTAL
) 
1243     GValue gvalue 
= { 0, }; 
1244     g_value_init( &gvalue
, G_TYPE_FLOAT 
); 
1245     g_value_set_float( &gvalue
, xalign 
); 
1246     g_object_set_property( G_OBJECT(m_renderer
), "xalign", &gvalue 
); 
1247     g_value_unset( &gvalue 
); 
1249     // vertical alignment: 
1251     gfloat yalign 
= 0.0; 
1252     if (align 
& wxALIGN_BOTTOM
) 
1254     else if (align 
& wxALIGN_CENTER_VERTICAL
) 
1257     GValue gvalue2 
= { 0, }; 
1258     g_value_init( &gvalue2
, G_TYPE_FLOAT 
); 
1259     g_value_set_float( &gvalue2
, yalign 
); 
1260     g_object_set_property( G_OBJECT(m_renderer
), "yalign", &gvalue2 
); 
1261     g_value_unset( &gvalue2 
); 
1264 int wxDataViewRenderer::GetAlignment() const 
1269     // horizontal alignment: 
1271     g_object_get( G_OBJECT(m_renderer
), "xalign", &gvalue
, NULL 
); 
1272     float xalign 
= g_value_get_float( &gvalue 
); 
1274         ret 
|= wxALIGN_LEFT
; 
1275     else if (xalign 
== 0.5) 
1276         ret 
|= wxALIGN_CENTER_HORIZONTAL
; 
1278         ret 
|= wxALIGN_RIGHT
; 
1279     g_value_unset( &gvalue 
); 
1282     // vertical alignment: 
1284     g_object_get( G_OBJECT(m_renderer
), "yalign", &gvalue
, NULL 
); 
1285     float yalign 
= g_value_get_float( &gvalue 
); 
1288     else if (yalign 
== 0.5) 
1289         ret 
|= wxALIGN_CENTER_VERTICAL
; 
1291         ret 
|= wxALIGN_BOTTOM
; 
1292     g_value_unset( &gvalue 
); 
1299 // --------------------------------------------------------- 
1300 // wxDataViewTextRenderer 
1301 // --------------------------------------------------------- 
1304 static void wxGtkTextRendererEditedCallback( GtkCellRendererText 
*renderer
, 
1305     gchar 
*arg1
, gchar 
*arg2
, gpointer user_data 
); 
1308 static void wxGtkTextRendererEditedCallback( GtkCellRendererText 
*renderer
, 
1309     gchar 
*arg1
, gchar 
*arg2
, gpointer user_data 
) 
1311     wxDataViewTextRenderer 
*cell 
= (wxDataViewTextRenderer
*) user_data
; 
1313     wxString tmp 
= wxGTK_CONV_BACK_FONT(arg2
, cell
->GetOwner()->GetOwner()->GetFont()); 
1314     wxVariant value 
= tmp
; 
1315     if (!cell
->Validate( value 
)) 
1318     wxDataViewModel 
*model 
= cell
->GetOwner()->GetOwner()->GetModel(); 
1320     GtkTreePath 
*path 
= gtk_tree_path_new_from_string( arg1 
); 
1322     cell
->GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter
, path 
); 
1323     wxDataViewItem 
item( (void*) iter
.user_data 
);; 
1324     gtk_tree_path_free( path 
); 
1326     unsigned int model_col 
= cell
->GetOwner()->GetModelColumn(); 
1328     model
->SetValue( value
, item
, model_col 
); 
1329     model
->ValueChanged( item
, model_col 
); 
1332 IMPLEMENT_CLASS(wxDataViewTextRenderer
, wxDataViewRenderer
) 
1334 wxDataViewTextRenderer::wxDataViewTextRenderer( const wxString 
&varianttype
, wxDataViewCellMode mode
, 
1336     wxDataViewRenderer( varianttype
, mode
, align 
) 
1338     m_renderer 
= (GtkCellRenderer
*) gtk_cell_renderer_text_new(); 
1340     if (mode 
& wxDATAVIEW_CELL_EDITABLE
) 
1342         GValue gvalue 
= { 0, }; 
1343         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1344         g_value_set_boolean( &gvalue
, true ); 
1345         g_object_set_property( G_OBJECT(m_renderer
), "editable", &gvalue 
); 
1346         g_value_unset( &gvalue 
); 
1348         g_signal_connect_after( m_renderer
, "edited", G_CALLBACK(wxGtkTextRendererEditedCallback
), this ); 
1352     SetAlignment(align
); 
1355 bool wxDataViewTextRenderer::SetValue( const wxVariant 
&value 
) 
1357     wxString tmp 
= value
; 
1359     GValue gvalue 
= { 0, }; 
1360     g_value_init( &gvalue
, G_TYPE_STRING 
); 
1361     g_value_set_string( &gvalue
, wxGTK_CONV_FONT( tmp
, GetOwner()->GetOwner()->GetFont() ) ); 
1362     g_object_set_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
1363     g_value_unset( &gvalue 
); 
1368 bool wxDataViewTextRenderer::GetValue( wxVariant 
&value 
) const 
1370     GValue gvalue 
= { 0, }; 
1371     g_value_init( &gvalue
, G_TYPE_STRING 
); 
1372     g_object_get_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
1373     wxString tmp 
= wxGTK_CONV_BACK_FONT( g_value_get_string( &gvalue 
), 
1374         wx_const_cast(wxDataViewTextRenderer
*, this)->GetOwner()->GetOwner()->GetFont() ); 
1375     g_value_unset( &gvalue 
); 
1382 void wxDataViewTextRenderer::SetAlignment( int align 
) 
1384     wxDataViewRenderer::SetAlignment(align
); 
1386     if (gtk_check_version(2,10,0)) 
1389     // horizontal alignment: 
1390     PangoAlignment pangoAlign 
= PANGO_ALIGN_LEFT
; 
1391     if (align 
& wxALIGN_RIGHT
) 
1392         pangoAlign 
= PANGO_ALIGN_RIGHT
; 
1393     else if (align 
& wxALIGN_CENTER_HORIZONTAL
) 
1394         pangoAlign 
= PANGO_ALIGN_CENTER
; 
1396     GValue gvalue 
= { 0, }; 
1397     g_value_init( &gvalue
, gtk_cell_renderer_mode_get_type() ); 
1398     g_value_set_enum( &gvalue
, pangoAlign 
); 
1399     g_object_set_property( G_OBJECT(m_renderer
), "alignment", &gvalue 
); 
1400     g_value_unset( &gvalue 
); 
1403 // --------------------------------------------------------- 
1404 // wxDataViewBitmapRenderer 
1405 // --------------------------------------------------------- 
1407 IMPLEMENT_CLASS(wxDataViewBitmapRenderer
, wxDataViewRenderer
) 
1409 wxDataViewBitmapRenderer::wxDataViewBitmapRenderer( const wxString 
&varianttype
, wxDataViewCellMode mode
, 
1411     wxDataViewRenderer( varianttype
, mode
, align 
) 
1413     m_renderer 
= (GtkCellRenderer
*) gtk_cell_renderer_pixbuf_new(); 
1416     SetAlignment(align
); 
1419 bool wxDataViewBitmapRenderer::SetValue( const wxVariant 
&value 
) 
1421     if (value
.GetType() == wxT("wxBitmap")) 
1426         // This may create a Pixbuf representation in the 
1427         // wxBitmap object (and it will stay there) 
1428         GdkPixbuf 
*pixbuf 
= bitmap
.GetPixbuf(); 
1430         GValue gvalue 
= { 0, }; 
1431         g_value_init( &gvalue
, G_TYPE_OBJECT 
); 
1432         g_value_set_object( &gvalue
, pixbuf 
); 
1433         g_object_set_property( G_OBJECT(m_renderer
), "pixbuf", &gvalue 
); 
1434         g_value_unset( &gvalue 
); 
1439     if (value
.GetType() == wxT("wxIcon")) 
1444         // This may create a Pixbuf representation in the 
1445         // wxBitmap object (and it will stay there) 
1446         GdkPixbuf 
*pixbuf 
= bitmap
.GetPixbuf(); 
1448         GValue gvalue 
= { 0, }; 
1449         g_value_init( &gvalue
, G_TYPE_OBJECT 
); 
1450         g_value_set_object( &gvalue
, pixbuf 
); 
1451         g_object_set_property( G_OBJECT(m_renderer
), "pixbuf", &gvalue 
); 
1452         g_value_unset( &gvalue 
); 
1460 bool wxDataViewBitmapRenderer::GetValue( wxVariant 
&value 
) const 
1465 // --------------------------------------------------------- 
1466 // wxDataViewToggleRenderer 
1467 // --------------------------------------------------------- 
1470 static void wxGtkToggleRendererToggledCallback( GtkCellRendererToggle 
*renderer
, 
1471     gchar 
*path
, gpointer user_data 
); 
1474 static void wxGtkToggleRendererToggledCallback( GtkCellRendererToggle 
*renderer
, 
1475     gchar 
*path
, gpointer user_data 
) 
1477     wxDataViewToggleRenderer 
*cell 
= (wxDataViewToggleRenderer
*) user_data
; 
1480     GValue gvalue 
= { 0, }; 
1481     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1482     g_object_get_property( G_OBJECT(renderer
), "active", &gvalue 
); 
1483     bool tmp 
= g_value_get_boolean( &gvalue 
); 
1484     g_value_unset( &gvalue 
); 
1488     wxVariant value 
= tmp
; 
1489     if (!cell
->Validate( value 
)) 
1492     wxDataViewModel 
*model 
= cell
->GetOwner()->GetOwner()->GetModel(); 
1494     GtkTreePath 
*gtk_path 
= gtk_tree_path_new_from_string( path 
); 
1496     cell
->GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter
, gtk_path 
); 
1497     wxDataViewItem 
item( (void*) iter
.user_data 
);; 
1498     gtk_tree_path_free( gtk_path 
); 
1500     unsigned int model_col 
= cell
->GetOwner()->GetModelColumn(); 
1502     model
->SetValue( value
, item
, model_col 
); 
1503     model
->ValueChanged( item
, model_col 
); 
1506 IMPLEMENT_CLASS(wxDataViewToggleRenderer
, wxDataViewRenderer
) 
1508 wxDataViewToggleRenderer::wxDataViewToggleRenderer( const wxString 
&varianttype
, 
1509                                                     wxDataViewCellMode mode
, int align 
) : 
1510     wxDataViewRenderer( varianttype
, mode
, align 
) 
1512     m_renderer 
= (GtkCellRenderer
*) gtk_cell_renderer_toggle_new(); 
1514     if (mode 
& wxDATAVIEW_CELL_ACTIVATABLE
) 
1516         g_signal_connect_after( m_renderer
, "toggled", 
1517                                 G_CALLBACK(wxGtkToggleRendererToggledCallback
), this ); 
1521         GValue gvalue 
= { 0, }; 
1522         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1523         g_value_set_boolean( &gvalue
, false ); 
1524         g_object_set_property( G_OBJECT(m_renderer
), "activatable", &gvalue 
); 
1525         g_value_unset( &gvalue 
); 
1529     SetAlignment(align
); 
1532 bool wxDataViewToggleRenderer::SetValue( const wxVariant 
&value 
) 
1536     GValue gvalue 
= { 0, }; 
1537     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1538     g_value_set_boolean( &gvalue
, tmp 
); 
1539     g_object_set_property( G_OBJECT(m_renderer
), "active", &gvalue 
); 
1540     g_value_unset( &gvalue 
); 
1545 bool wxDataViewToggleRenderer::GetValue( wxVariant 
&value 
) const 
1547     GValue gvalue 
= { 0, }; 
1548     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1549     g_object_get_property( G_OBJECT(m_renderer
), "active", &gvalue 
); 
1550     bool tmp 
= g_value_get_boolean( &gvalue 
); 
1551     g_value_unset( &gvalue 
); 
1558 // --------------------------------------------------------- 
1559 // wxDataViewCustomRenderer 
1560 // --------------------------------------------------------- 
1562 class wxDataViewCtrlDC
: public wxWindowDC
 
1565     wxDataViewCtrlDC( wxDataViewCtrl 
*window 
) 
1567         GtkWidget 
*widget 
= window
->m_treeview
; 
1571         m_context 
= window
->GtkGetPangoDefaultContext(); 
1572         m_layout 
= pango_layout_new( m_context 
); 
1573         m_fontdesc 
= pango_font_description_copy( widget
->style
->font_desc 
); 
1575         m_cmap 
= gtk_widget_get_colormap( widget 
? widget 
: window
->m_widget 
); 
1577         // Set m_window later 
1579         // m_owner = window; 
1583 // --------------------------------------------------------- 
1584 // wxDataViewCustomRenderer 
1585 // --------------------------------------------------------- 
1587 IMPLEMENT_CLASS(wxDataViewCustomRenderer
, wxDataViewRenderer
) 
1589 wxDataViewCustomRenderer::wxDataViewCustomRenderer( const wxString 
&varianttype
, 
1590                                                     wxDataViewCellMode mode
, int align
, 
1592     wxDataViewRenderer( varianttype
, mode
, align 
) 
1602 bool wxDataViewCustomRenderer::Init(wxDataViewCellMode mode
, int align
) 
1604     GtkWxCellRenderer 
*renderer 
= (GtkWxCellRenderer 
*) gtk_wx_cell_renderer_new(); 
1605     renderer
->cell 
= this; 
1607     m_renderer 
= (GtkCellRenderer
*) renderer
; 
1610     SetAlignment(align
); 
1615 wxDataViewCustomRenderer::~wxDataViewCustomRenderer() 
1621 wxDC 
*wxDataViewCustomRenderer::GetDC() 
1625         if (GetOwner() == NULL
) 
1627         if (GetOwner()->GetOwner() == NULL
) 
1629         m_dc 
= new wxDataViewCtrlDC( GetOwner()->GetOwner() ); 
1635 // --------------------------------------------------------- 
1636 // wxDataViewProgressRenderer 
1637 // --------------------------------------------------------- 
1639 IMPLEMENT_CLASS(wxDataViewProgressRenderer
, wxDataViewCustomRenderer
) 
1641 wxDataViewProgressRenderer::wxDataViewProgressRenderer( const wxString 
&label
, 
1642     const wxString 
&varianttype
, wxDataViewCellMode mode
, int align 
) : 
1643     wxDataViewCustomRenderer( varianttype
, mode
, align
, true ) 
1649     if (!gtk_check_version(2,6,0)) 
1651         m_renderer 
= (GtkCellRenderer
*) gtk_cell_renderer_progress_new(); 
1653         GValue gvalue 
= { 0, }; 
1654         g_value_init( &gvalue
, G_TYPE_STRING 
); 
1656         // FIXME: font encoding support 
1657         g_value_set_string( &gvalue
, wxGTK_CONV_SYS(m_label
) ); 
1658         g_object_set_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
1659         g_value_unset( &gvalue 
); 
1662         SetAlignment(align
); 
1667         // Use custom cell code 
1668         wxDataViewCustomRenderer::Init(mode
, align
); 
1672 wxDataViewProgressRenderer::~wxDataViewProgressRenderer() 
1676 bool wxDataViewProgressRenderer::SetValue( const wxVariant 
&value 
) 
1679     if (!gtk_check_version(2,6,0)) 
1681         gint tmp 
= (long) value
; 
1682         GValue gvalue 
= { 0, }; 
1683         g_value_init( &gvalue
, G_TYPE_INT 
); 
1684         g_value_set_int( &gvalue
, tmp 
); 
1685         g_object_set_property( G_OBJECT(m_renderer
), "value", &gvalue 
); 
1686         g_value_unset( &gvalue 
); 
1691         m_value 
= (long) value
; 
1693         if (m_value 
< 0) m_value 
= 0; 
1694         if (m_value 
> 100) m_value 
= 100; 
1700 bool wxDataViewProgressRenderer::GetValue( wxVariant 
&value 
) const 
1705 bool wxDataViewProgressRenderer::Render( wxRect cell
, wxDC 
*dc
, int state 
) 
1707     double pct 
= (double)m_value 
/ 100.0; 
1709     bar
.width 
= (int)(cell
.width 
* pct
); 
1710     dc
->SetPen( *wxTRANSPARENT_PEN 
); 
1711     dc
->SetBrush( *wxBLUE_BRUSH 
); 
1712     dc
->DrawRectangle( bar 
); 
1714     dc
->SetBrush( *wxTRANSPARENT_BRUSH 
); 
1715     dc
->SetPen( *wxBLACK_PEN 
); 
1716     dc
->DrawRectangle( cell 
); 
1721 wxSize 
wxDataViewProgressRenderer::GetSize() const 
1723     return wxSize(40,12); 
1726 // --------------------------------------------------------- 
1727 // wxDataViewDateRenderer 
1728 // --------------------------------------------------------- 
1730 class wxDataViewDateRendererPopupTransient
: public wxPopupTransientWindow
 
1733     wxDataViewDateRendererPopupTransient( wxWindow
* parent
, wxDateTime 
*value
, 
1734         wxDataViewModel 
*model
, const wxDataViewItem 
&item
, unsigned int col 
) : 
1735         wxPopupTransientWindow( parent
, wxBORDER_SIMPLE 
) 
1740         m_cal 
= new wxCalendarCtrl( this, -1, *value 
); 
1741         wxBoxSizer 
*sizer 
= new wxBoxSizer( wxHORIZONTAL 
); 
1742         sizer
->Add( m_cal
, 1, wxGROW 
); 
1747     virtual void OnDismiss() 
1751     void OnCalendar( wxCalendarEvent 
&event 
); 
1753     wxCalendarCtrl   
*m_cal
; 
1754     wxDataViewModel  
*m_model
; 
1755     wxDataViewItem    m_item
; 
1759     DECLARE_EVENT_TABLE() 
1762 BEGIN_EVENT_TABLE(wxDataViewDateRendererPopupTransient
,wxPopupTransientWindow
) 
1763     EVT_CALENDAR( -1, wxDataViewDateRendererPopupTransient::OnCalendar 
) 
1766 void wxDataViewDateRendererPopupTransient::OnCalendar( wxCalendarEvent 
&event 
) 
1768     wxDateTime date 
= event
.GetDate(); 
1769     wxVariant value 
= date
; 
1770     m_model
->SetValue( value
, m_item
, m_col 
); 
1771     m_model
->ValueChanged( m_item
, m_col 
); 
1775 IMPLEMENT_CLASS(wxDataViewDateRenderer
, wxDataViewCustomRenderer
) 
1777 wxDataViewDateRenderer::wxDataViewDateRenderer( const wxString 
&varianttype
, 
1778                         wxDataViewCellMode mode
, int align 
) : 
1779     wxDataViewCustomRenderer( varianttype
, mode
, align 
) 
1782     SetAlignment(align
); 
1785 bool wxDataViewDateRenderer::SetValue( const wxVariant 
&value 
) 
1787     m_date 
= value
.GetDateTime(); 
1792 bool wxDataViewDateRenderer::GetValue( wxVariant 
&value 
) const 
1797 bool wxDataViewDateRenderer::Render( wxRect cell
, wxDC 
*dc
, int state 
) 
1799     dc
->SetFont( GetOwner()->GetOwner()->GetFont() ); 
1800     wxString tmp 
= m_date
.FormatDate(); 
1801     dc
->DrawText( tmp
, cell
.x
, cell
.y 
); 
1806 wxSize 
wxDataViewDateRenderer::GetSize() const 
1808     wxString tmp 
= m_date
.FormatDate(); 
1810     GetView()->GetTextExtent( tmp
, &x
, &y
, &d 
); 
1811     return wxSize(x
,y
+d
); 
1814 bool wxDataViewDateRenderer::Activate( wxRect cell
, wxDataViewModel 
*model
, 
1815                                        const wxDataViewItem 
&item
, unsigned int col 
) 
1818     model
->GetValue( variant
, item
, col 
); 
1819     wxDateTime value 
= variant
.GetDateTime(); 
1821     wxDataViewDateRendererPopupTransient 
*popup 
= new wxDataViewDateRendererPopupTransient( 
1822         GetOwner()->GetOwner()->GetParent(), &value
, model
, item
, col 
); 
1823     wxPoint pos 
= wxGetMousePosition(); 
1826     popup
->Popup( popup
->m_cal 
); 
1831 // --------------------------------------------------------- 
1833 // --------------------------------------------------------- 
1837 gtk_dataview_header_button_press_callback( GtkWidget 
*widget
, 
1838                                            GdkEventButton 
*gdk_event
, 
1839                                            wxDataViewColumn 
*column 
) 
1841     if (gdk_event
->type 
!= GDK_BUTTON_PRESS
) 
1844     if (gdk_event
->button 
== 1) 
1846         wxDataViewCtrl 
*dv 
= column
->GetOwner(); 
1847         wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK
, dv
->GetId() ); 
1848         event
.SetDataViewColumn( column 
); 
1849         event
.SetModel( dv
->GetModel() ); 
1850         if (dv
->GetEventHandler()->ProcessEvent( event 
)) 
1858 static void wxGtkTreeCellDataFunc( GtkTreeViewColumn 
*column
, 
1859                             GtkCellRenderer 
*cell
, 
1860                             GtkTreeModel 
*model
, 
1866 static void wxGtkTreeCellDataFunc( GtkTreeViewColumn 
*column
, 
1867                             GtkCellRenderer 
*renderer
, 
1868                             GtkTreeModel 
*model
, 
1872     g_return_if_fail (GTK_IS_WX_TREE_MODEL (model
)); 
1873     GtkWxTreeModel 
*tree_model 
= (GtkWxTreeModel 
*) model
; 
1875     wxDataViewRenderer 
*cell 
= (wxDataViewRenderer
*) data
; 
1877     wxDataViewItem 
item( (void*) iter
->user_data 
); 
1880     tree_model
->internal
->GetDataViewModel()->GetValue( value
, item
, cell
->GetOwner()->GetModelColumn() ); 
1882     if (value
.GetType() != cell
->GetVariantType()) 
1883         wxLogError( wxT("Wrong type, required: %s but: %s"), 
1884                     value
.GetType().c_str(), 
1885                     cell
->GetVariantType().c_str() ); 
1887     cell
->SetValue( value 
); 
1890     wxListItemAttr attr
; 
1891     tree_model
->model
->GetAttr( attr
, cell
->GetOwner()->GetModelColumn(), model_row 
); 
1893     if (attr
.HasBackgroundColour()) 
1895         wxColour colour 
= attr
.GetBackgroundColour(); 
1896         const GdkColor 
* const gcol 
= colour
.GetColor(); 
1898         GValue gvalue 
= { 0, }; 
1899         g_value_init( &gvalue
, GDK_TYPE_COLOR 
); 
1900         g_value_set_boxed( &gvalue
, gcol 
); 
1901         g_object_set_property( G_OBJECT(renderer
), "cell-background_gdk", &gvalue 
); 
1902         g_value_unset( &gvalue 
); 
1906         GValue gvalue 
= { 0, }; 
1907         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1908         g_value_set_boolean( &gvalue
, FALSE 
); 
1909         g_object_set_property( G_OBJECT(renderer
), "cell-background-set", &gvalue 
); 
1910         g_value_unset( &gvalue 
); 
1916 IMPLEMENT_CLASS(wxDataViewColumn
, wxDataViewColumnBase
) 
1918 wxDataViewColumn::wxDataViewColumn( const wxString 
&title
, wxDataViewRenderer 
*cell
, 
1919                                     unsigned int model_column
, int width
, 
1920                                     wxAlignment align
, int flags 
) : 
1921     wxDataViewColumnBase( title
, cell
, model_column
, width
, align
, flags 
) 
1923     Init( align
, flags
, width 
); 
1925     gtk_tree_view_column_set_clickable( GTK_TREE_VIEW_COLUMN(m_column
), TRUE 
); 
1929 wxDataViewColumn::wxDataViewColumn( const wxBitmap 
&bitmap
, wxDataViewRenderer 
*cell
, 
1930                                     unsigned int model_column
, int width
, 
1931                                     wxAlignment align
, int flags 
) : 
1932     wxDataViewColumnBase( bitmap
, cell
, model_column
, width
, align
, flags 
) 
1934     Init( align
, flags
, width 
); 
1936     SetBitmap( bitmap 
); 
1939 void wxDataViewColumn::Init(wxAlignment align
, int flags
, int width
) 
1941     m_isConnected 
= false; 
1943     GtkCellRenderer 
*renderer 
= (GtkCellRenderer 
*) GetRenderer()->GetGtkHandle(); 
1944     GtkTreeViewColumn 
*column 
= gtk_tree_view_column_new(); 
1945     m_column 
= (GtkWidget
*) column
; 
1948     SetAlignment( align 
); 
1950     // NOTE: we prefer not to call SetMinWidth(wxDVC_DEFAULT_MINWIDTH); 
1951     //       as GTK+ is smart and unless explicitely told, will set the minimal 
1952     //       width to the title's lenght, which is a better default 
1954     // the GTK_TREE_VIEW_COLUMN_FIXED is required by the "fixed height" mode 
1955     // that we use for the wxDataViewCtrl 
1956     gtk_tree_view_column_set_fixed_width( column
, width 
< 0 ? wxDVC_DEFAULT_WIDTH 
: width 
); 
1957     gtk_tree_view_column_set_sizing( column
, GTK_TREE_VIEW_COLUMN_FIXED 
); 
1959     gtk_tree_view_column_pack_end( column
, renderer
, TRUE 
); 
1961     gtk_tree_view_column_set_cell_data_func( column
, renderer
, 
1962         wxGtkTreeCellDataFunc
, (gpointer
) GetRenderer(), NULL 
); 
1965 wxDataViewColumn::~wxDataViewColumn() 
1969 void wxDataViewColumn::OnInternalIdle() 
1974     if (GTK_WIDGET_REALIZED(GetOwner()->m_treeview
)) 
1976         GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
1979             g_signal_connect(column
->button
, "button_press_event", 
1980                       G_CALLBACK (gtk_dataview_header_button_press_callback
), this); 
1982             m_isConnected 
= true; 
1987 void wxDataViewColumn::SetOwner( wxDataViewCtrl 
*owner 
) 
1989     wxDataViewColumnBase::SetOwner( owner 
); 
1991     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
1993     gtk_tree_view_column_set_title( column
, wxGTK_CONV_FONT(GetTitle(), GetOwner()->GetFont() ) ); 
1996 void wxDataViewColumn::SetTitle( const wxString 
&title 
) 
1998     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2002         // disconnect before column->button gets recreated 
2003         g_signal_handlers_disconnect_by_func( column
->button
, 
2004                       (GtkWidget
*) gtk_dataview_header_button_press_callback
, this); 
2006         m_isConnected 
= false; 
2009     // FIXME: can it really happen that we don't have the owner here?? 
2010     wxDataViewCtrl 
*ctrl 
= GetOwner(); 
2011     gtk_tree_view_column_set_title( column
, ctrl 
? wxGTK_CONV_FONT(title
, ctrl
->GetFont()) 
2012                                                  : wxGTK_CONV_SYS(title
) ); 
2014     gtk_tree_view_column_set_widget( column
, NULL 
); 
2017 wxString 
wxDataViewColumn::GetTitle() const 
2019     const gchar 
*str 
= gtk_tree_view_column_get_title( GTK_TREE_VIEW_COLUMN(m_column
) ); 
2020     return wxConvFileName
->cMB2WX(str
); 
2023 void wxDataViewColumn::SetBitmap( const wxBitmap 
&bitmap 
) 
2025     wxDataViewColumnBase::SetBitmap( bitmap 
); 
2027     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2030         GtkImage 
*gtk_image 
= GTK_IMAGE( gtk_image_new() ); 
2032         GdkBitmap 
*mask 
= (GdkBitmap 
*) NULL
; 
2033         if (bitmap
.GetMask()) 
2034             mask 
= bitmap
.GetMask()->GetBitmap(); 
2036         if (bitmap
.HasPixbuf()) 
2038             gtk_image_set_from_pixbuf(GTK_IMAGE(gtk_image
), 
2039                                       bitmap
.GetPixbuf()); 
2043             gtk_image_set_from_pixmap(GTK_IMAGE(gtk_image
), 
2044                                       bitmap
.GetPixmap(), mask
); 
2046         gtk_widget_show( GTK_WIDGET(gtk_image
) ); 
2048         gtk_tree_view_column_set_widget( column
, GTK_WIDGET(gtk_image
) ); 
2052         gtk_tree_view_column_set_widget( column
, NULL 
); 
2056 void wxDataViewColumn::SetHidden( bool hidden 
) 
2058     gtk_tree_view_column_set_visible( GTK_TREE_VIEW_COLUMN(m_column
), !hidden 
); 
2061 void wxDataViewColumn::SetResizeable( bool resizeable 
) 
2063     gtk_tree_view_column_set_resizable( GTK_TREE_VIEW_COLUMN(m_column
), resizeable 
); 
2066 void wxDataViewColumn::SetAlignment( wxAlignment align 
) 
2068     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2070     gfloat xalign 
= 0.0; 
2071     if (align 
== wxALIGN_RIGHT
) 
2073     if (align 
== wxALIGN_CENTER_HORIZONTAL 
|| 
2074         align 
== wxALIGN_CENTER
) 
2077     gtk_tree_view_column_set_alignment( column
, xalign 
); 
2080 wxAlignment 
wxDataViewColumn::GetAlignment() const 
2082     gfloat xalign 
= gtk_tree_view_column_get_alignment( GTK_TREE_VIEW_COLUMN(m_column
) ); 
2085         return wxALIGN_RIGHT
; 
2087         return wxALIGN_CENTER_HORIZONTAL
; 
2089     return wxALIGN_LEFT
; 
2092 void wxDataViewColumn::SetSortable( bool sortable 
) 
2094     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2097         gtk_tree_view_column_set_sort_column_id( column
, GetModelColumn() ); 
2099         gtk_tree_view_column_set_sort_column_id( column
, -1 ); 
2102 bool wxDataViewColumn::IsSortable() const 
2104     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2105     return (gtk_tree_view_column_get_sort_column_id( column 
) != -1); 
2108 bool wxDataViewColumn::IsResizeable() const 
2110     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2111     return gtk_tree_view_column_get_resizable( column 
); 
2114 bool wxDataViewColumn::IsHidden() const 
2116     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2117     return !gtk_tree_view_column_get_visible( column 
); 
2120 void wxDataViewColumn::SetSortOrder( bool ascending 
) 
2122     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2125         gtk_tree_view_column_set_sort_order( column
, GTK_SORT_ASCENDING 
); 
2127         gtk_tree_view_column_set_sort_order( column
, GTK_SORT_DESCENDING 
); 
2130 bool wxDataViewColumn::IsSortOrderAscending() const 
2132     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
2134     return (gtk_tree_view_column_get_sort_order( column 
) != GTK_SORT_DESCENDING
); 
2137 void wxDataViewColumn::SetMinWidth( int width 
) 
2139     gtk_tree_view_column_set_min_width( GTK_TREE_VIEW_COLUMN(m_column
), width 
); 
2142 int wxDataViewColumn::GetMinWidth() const 
2144     return gtk_tree_view_column_get_min_width( GTK_TREE_VIEW_COLUMN(m_column
) ); 
2147 int wxDataViewColumn::GetWidth() const 
2149     return gtk_tree_view_column_get_width( GTK_TREE_VIEW_COLUMN(m_column
) ); 
2152 void wxDataViewColumn::SetWidth( int width 
) 
2154     gtk_tree_view_column_set_fixed_width( GTK_TREE_VIEW_COLUMN(m_column
), width 
); 
2158 //----------------------------------------------------------------------------- 
2159 // wxGtkTreeModelNode 
2160 //----------------------------------------------------------------------------- 
2162 void wxGtkTreeModelNode::Resort() 
2164     g_internal 
= m_internal
; 
2166     size_t child_count 
= GetChildCount(); 
2167     if (child_count 
== 0) 
2170     size_t node_count 
= GetNodesCount(); 
2172     if (child_count 
== 1) 
2174         if (node_count 
== 1) 
2176             wxGtkTreeModelNode 
*node 
= m_nodes
.Item( 0 ); 
2182     wxGtkTreeModelChildren 
*new_array 
= new wxGtkTreeModelChildren( wxGtkTreeModelNodeCmp 
); 
2185     for (pos 
= 0; pos 
< child_count
; pos
++) 
2186         new_array
->Add( m_children
->Item( pos 
) ); 
2188     gint 
*new_order 
= new gint
[child_count
]; 
2190     for (pos 
= 0; pos 
< child_count
; pos
++) 
2192         void *id 
= new_array
->Item( pos 
); 
2194         for (old_pos 
= 0; old_pos 
< child_count
; old_pos
++) 
2196             if (id 
== m_children
->Item(old_pos
)) 
2198                 new_order
[pos
] = old_pos
; 
2204 //    for (pos = 0; pos < count; pos++) 
2205 //        m_children->Clear(); 
2208     m_children 
= new_array
; 
2210     GtkTreeModel 
*gtk_tree_model 
= GTK_TREE_MODEL( m_internal
->GetGtkModel() ); 
2212     GtkTreePath 
*path 
= gtk_tree_path_new (); 
2213     wxGtkTreeModelNode 
*parent 
= GetParent(); 
2214     void *id 
= GetItem().GetID(); 
2218         int pos 
= parent
->GetChildren().Index( id 
); 
2219         gtk_tree_path_prepend_index( path
, pos 
); 
2220         id 
= parent
->GetItem().GetID(); 
2221         parent 
= parent
->GetParent(); 
2225     iter
.user_data 
= id
; 
2226     iter
.stamp 
= m_internal
->GetGtkModel()->stamp
; 
2227     gtk_tree_model_rows_reordered( gtk_tree_model
, path
, &iter
, new_order 
); 
2229     gtk_tree_path_free (path
); 
2231     delete [] new_order
; 
2233     for (pos 
= 0; pos 
< node_count
; pos
++) 
2235         wxGtkTreeModelNode 
*node 
= m_nodes
.Item( pos 
); 
2240 //----------------------------------------------------------------------------- 
2241 // wxDataViewCtrlInternal 
2242 //----------------------------------------------------------------------------- 
2244 wxDataViewCtrlInternal::wxDataViewCtrlInternal( wxDataViewCtrl 
*owner
,  
2245     wxDataViewModel 
*wx_model
, GtkWxTreeModel 
*gtk_model 
) 
2248     m_wx_model 
= wx_model
;  
2249     m_gtk_model 
= gtk_model
;  
2251     m_sort_order 
= GTK_SORT_ASCENDING
; 
2256 wxDataViewCtrlInternal::~wxDataViewCtrlInternal() 
2258     g_object_unref( m_gtk_model 
); 
2261 void wxDataViewCtrlInternal::InitTree() 
2263     wxDataViewItem item
; 
2264     m_root 
= new wxGtkTreeModelNode( NULL
, item
, this ); 
2266     BuildBranch( m_root 
); 
2269 void wxDataViewCtrlInternal::BuildBranch( wxGtkTreeModelNode 
*node 
) 
2271     if (node
->GetChildCount() == 0) 
2273         wxDataViewItem child 
= m_wx_model
->GetFirstChild( node
->GetItem() ); 
2274         while (child
.IsOk()) 
2276             if (m_wx_model
->IsContainer( child 
)) 
2277                 node
->AddNode( new wxGtkTreeModelNode( node
, child
, this ) ); 
2279                 node
->AddLeave( child
.GetID() ); 
2281             // Don't send any events here 
2283             child 
= m_wx_model
->GetNextSibling( child 
); 
2288 void wxDataViewCtrlInternal::Resort() 
2293 bool wxDataViewCtrlInternal::ItemAdded( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
) 
2295     wxGtkTreeModelNode 
*parent_node 
= FindNode( parent 
); 
2296     if (m_wx_model
->IsContainer( item 
)) 
2297         parent_node
->AddNode( new wxGtkTreeModelNode( parent_node
, item
, this ) ); 
2299         parent_node
->AddLeave( item
.GetID() ); 
2301     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_ADDED
, m_owner
->GetId() ); 
2302     event
.SetEventObject( m_owner 
); 
2303     event
.SetModel( m_owner
->GetModel() ); 
2304     event
.SetItem( item 
); 
2305     m_owner
->GetEventHandler()->ProcessEvent( event 
); 
2310 bool wxDataViewCtrlInternal::ItemDeleted( const wxDataViewItem 
&parent
, const wxDataViewItem 
&item 
) 
2312     wxGtkTreeModelNode 
*parent_node 
= FindNode( parent 
); 
2313     parent_node
->DeleteChild( item
.GetID() ); 
2315     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_DELETED
, m_owner
->GetId() ); 
2316     event
.SetEventObject( m_owner 
); 
2317     event
.SetModel( m_owner
->GetModel() ); 
2318     event
.SetItem( item 
); 
2319     m_owner
->GetEventHandler()->ProcessEvent( event 
); 
2324 bool wxDataViewCtrlInternal::ItemChanged( const wxDataViewItem 
&item 
) 
2326     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_CHANGED
, m_owner
->GetId() ); 
2327     event
.SetEventObject( m_owner 
); 
2328     event
.SetModel( m_owner
->GetModel() ); 
2329     event
.SetItem( item 
); 
2330     m_owner
->GetEventHandler()->ProcessEvent( event 
); 
2335 bool wxDataViewCtrlInternal::ValueChanged( const wxDataViewItem 
&item
, unsigned int col 
) 
2337     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_MODEL_VALUE_CHANGED
, m_owner
->GetId() ); 
2338     event
.SetEventObject( m_owner 
); 
2339     event
.SetModel( m_owner
->GetModel() ); 
2340     event
.SetColumn( col 
); 
2341     event
.SetItem( item 
); 
2342     m_owner
->GetEventHandler()->ProcessEvent( event 
); 
2347 bool wxDataViewCtrlInternal::Cleared() 
2349     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_MODEL_CLEARED
, m_owner
->GetId() ); 
2350     event
.SetEventObject( m_owner 
); 
2351     event
.SetModel( m_owner
->GetModel() ); 
2352     m_owner
->GetEventHandler()->ProcessEvent( event 
); 
2357 gboolean 
wxDataViewCtrlInternal::get_iter( GtkTreeIter 
*iter
, GtkTreePath 
*path 
) 
2361     int depth 
= gtk_tree_path_get_depth( path 
); 
2363     wxGtkTreeModelNode 
*node 
= m_root
; 
2366     for (i 
= 0; i 
< depth
; i
++)     
2368         BuildBranch( node 
); 
2370         gint pos 
= gtk_tree_path_get_indices (path
)[i
]; 
2371         if (pos 
< 0) return FALSE
; 
2372         if ((size_t)pos 
>= node
->GetChildCount()) return FALSE
; 
2374         void* id 
= node
->GetChildren().Item( (size_t) pos 
); 
2378             iter
->stamp 
= m_gtk_model
->stamp
; 
2379             iter
->user_data 
= id
; 
2383         size_t count 
= node
->GetNodes().GetCount(); 
2385         for (pos2 
= 0; pos2 
< count
; pos2
++) 
2387             wxGtkTreeModelNode 
*child_node 
= node
->GetNodes().Item( pos2 
); 
2388             if (child_node
->GetItem().GetID() == id
) 
2399 GtkTreePath 
*wxDataViewCtrlInternal::get_path( GtkTreeIter 
*iter 
) 
2403     GtkTreePath 
*retval 
= gtk_tree_path_new (); 
2404     void *id 
= iter
->user_data
;     
2406     wxGtkTreeModelNode 
*node 
= FindParentNode( iter 
); 
2409         int pos 
= node
->GetChildren().Index( id 
); 
2410         gtk_tree_path_prepend_index( retval
, pos 
); 
2412         id 
= node
->GetItem().GetID(); 
2413         node 
= node
->GetParent(); 
2419 GtkTreePath 
*wxDataViewCtrlInternal::get_path_safe( GtkTreeIter 
*iter 
) 
2423     GtkTreePath 
*retval 
= gtk_tree_path_new (); 
2424     void *id 
= iter
->user_data
;     
2426     wxGtkTreeModelNode 
*node 
= FindParentNode( iter 
); 
2430         for (pos 
= 0; pos 
< node
->GetChildren().GetCount(); pos
++) 
2432             if (id 
== node
->GetChildren().Item( pos 
)) 
2434                 gtk_tree_path_prepend_index( retval
, (int) pos 
); 
2439         id 
= node
->GetItem().GetID(); 
2440         node 
= node
->GetParent(); 
2446 gboolean 
wxDataViewCtrlInternal::iter_next( GtkTreeIter 
*iter 
) 
2450     wxGtkTreeModelNode 
*parent 
= FindParentNode( iter 
); 
2451     if( parent 
== NULL 
) 
2454     unsigned int pos 
= parent
->GetChildren().Index( iter
->user_data 
); 
2456     if (pos 
== parent
->GetChildCount()-1) 
2459     iter
->stamp 
= m_gtk_model
->stamp
; 
2460     iter
->user_data 
= parent
->GetChildren().Item( pos
+1 ); 
2465 gboolean 
wxDataViewCtrlInternal::iter_children( GtkTreeIter 
*iter
, GtkTreeIter 
*parent 
) 
2469     wxDataViewItem 
item( (void*) parent
->user_data 
); 
2471     if (!m_wx_model
->IsContainer( item 
)) 
2474     wxGtkTreeModelNode 
*parent_node 
= FindNode( parent 
); 
2475     BuildBranch( parent_node 
); 
2477     if (parent_node
->GetChildCount() == 0) 
2480     iter
->stamp 
= m_gtk_model
->stamp
; 
2481     iter
->user_data 
= (gpointer
) parent_node
->GetChildren().Item( 0 ); 
2486 gboolean 
wxDataViewCtrlInternal::iter_has_child( GtkTreeIter 
*iter 
) 
2490     wxDataViewItem 
item( (void*) iter
->user_data 
); 
2491     bool is_container 
= m_wx_model
->IsContainer( item 
); 
2496     wxGtkTreeModelNode 
*node 
= FindNode( iter 
); 
2497     BuildBranch( node 
); 
2499     return (node
->GetChildCount() > 0); 
2502 gint 
wxDataViewCtrlInternal::iter_n_children( GtkTreeIter 
*iter 
) 
2506     wxDataViewItem 
item( (void*) iter
->user_data 
); 
2508     if (!m_wx_model
->IsContainer( item 
)) 
2511     wxGtkTreeModelNode 
*parent_node 
= FindNode( iter 
); 
2512     BuildBranch( parent_node 
); 
2514     // wxPrintf( "iter_n_children %d\n", parent_node->GetChildCount() ); 
2516     return parent_node
->GetChildCount(); 
2519 gboolean 
wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter 
*iter
, GtkTreeIter 
*parent
, gint n 
) 
2524     if (parent
) id 
= (void*) parent
->user_data
; 
2525     wxDataViewItem 
item( id 
); 
2527     if (!m_wx_model
->IsContainer( item 
)) 
2530     wxGtkTreeModelNode 
*parent_node 
= FindNode( parent 
); 
2531     BuildBranch( parent_node 
); 
2533     // wxPrintf( "iter_nth_child %d\n", n ); 
2535     iter
->stamp 
= m_gtk_model
->stamp
; 
2536     iter
->user_data 
= parent_node
->GetChildren().Item( n 
); 
2541 gboolean 
wxDataViewCtrlInternal::iter_parent( GtkTreeIter 
*iter
, GtkTreeIter 
*child 
) 
2545     wxGtkTreeModelNode 
*node 
= FindParentNode( child 
); 
2549     iter
->stamp 
= m_gtk_model
->stamp
; 
2550     iter
->user_data 
= (gpointer
) node
->GetItem().GetID(); 
2555 static wxGtkTreeModelNode
* 
2556 wxDataViewCtrlInternal_FindNode( wxDataViewModel 
* model
, wxGtkTreeModelNode 
*treeNode
, const wxDataViewItem 
&item 
) 
2562     list
.DeleteContents( true ); 
2563     wxDataViewItem 
it( item 
); 
2566         wxDataViewItem 
* pItem 
= new wxDataViewItem( it 
); 
2567         list
.Insert( pItem 
); 
2568         it 
= model
->GetParent( it 
); 
2571     wxGtkTreeModelNode 
* node 
= treeNode
; 
2572     for( ItemList::compatibility_iterator n 
= list
.GetFirst(); n
; n 
= n
->GetNext() ) 
2574         if( node 
&& node
->GetNodes().GetCount() != 0 ) 
2576             int len 
= node
->GetNodes().GetCount(); 
2577             wxGtkTreeModelNodes nodes 
= node
->GetNodes(); 
2579             for( ; j 
< len
; j 
++) 
2581                 if( nodes
[j
]->GetItem() == *(n
->GetData())) 
2600 wxGtkTreeModelNode 
*wxDataViewCtrlInternal::FindNode( GtkTreeIter 
*iter 
) 
2605     wxDataViewItem 
item( (void*) iter
->user_data 
); 
2609     wxGtkTreeModelNode 
*result 
= wxDataViewCtrlInternal_FindNode( m_wx_model
, m_root
, item 
); 
2613         wxPrintf( "Not found %d\n", (int) iter
->user_data 
); 
2621 wxGtkTreeModelNode 
*wxDataViewCtrlInternal::FindNode( const wxDataViewItem 
&item 
) 
2626     wxGtkTreeModelNode 
*result 
= wxDataViewCtrlInternal_FindNode( m_wx_model
, m_root
, item 
); 
2630         wxPrintf( "Not found %d\n", (int) item
.GetID() ); 
2638 static wxGtkTreeModelNode
* 
2639 wxDataViewCtrlInternal_FindParentNode( wxDataViewModel 
* model
, wxGtkTreeModelNode 
*treeNode
, const wxDataViewItem 
&item 
) 
2645     list
.DeleteContents( true ); 
2649     wxDataViewItem 
it( model
->GetParent( item 
) ); 
2652         wxDataViewItem 
* pItem 
= new wxDataViewItem( it 
); 
2653         list
.Insert( pItem 
); 
2654         it 
= model
->GetParent( it 
); 
2657     wxGtkTreeModelNode 
* node 
= treeNode
; 
2658     for( ItemList::compatibility_iterator n 
= list
.GetFirst(); n
; n 
= n
->GetNext() ) 
2660         if( node 
&& node
->GetNodes().GetCount() != 0 ) 
2662             int len 
= node
->GetNodes().GetCount(); 
2663             wxGtkTreeModelNodes nodes 
= node
->GetNodes(); 
2665             for( ; j 
< len
; j 
++) 
2667                 if( nodes
[j
]->GetItem() == *(n
->GetData())) 
2682     //Examine whether the node is item's parent node 
2683     int len 
= node
->GetChildCount(); 
2684     for( int i 
= 0; i 
< len 
; i 
++ ) 
2686         if( node
->GetChildren().Item( i 
) == item
.GetID() ) 
2692 wxGtkTreeModelNode 
*wxDataViewCtrlInternal::FindParentNode( GtkTreeIter 
*iter 
) 
2697     wxDataViewItem 
item( (void*) iter
->user_data 
); 
2701     return wxDataViewCtrlInternal_FindParentNode( m_wx_model
, m_root
, item 
); 
2704 wxGtkTreeModelNode 
*wxDataViewCtrlInternal::FindParentNode( const wxDataViewItem 
&item 
) 
2709     return wxDataViewCtrlInternal_FindParentNode( m_wx_model
, m_root
, item 
); 
2712 //----------------------------------------------------------------------------- 
2713 // wxDataViewCtrl signal callbacks 
2714 //----------------------------------------------------------------------------- 
2717 wxdataview_selection_changed_callback( GtkTreeSelection
* selection
, wxDataViewCtrl 
*dv 
) 
2719     if (!GTK_WIDGET_REALIZED(dv
->m_widget
)) 
2722     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_SELECTED
, dv
->GetId() ); 
2723     event
.SetItem( dv
->GetSelection() ); 
2724     event
.SetModel( dv
->GetModel() ); 
2725     dv
->GetEventHandler()->ProcessEvent( event 
); 
2729 wxdataview_row_activated_callback( GtkTreeView
* treeview
, GtkTreePath 
*path
, 
2730                                    GtkTreeViewColumn 
*column
, wxDataViewCtrl 
*dv 
) 
2732     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED
, dv
->GetId() ); 
2735     dv
->GtkGetInternal()->get_iter( &iter
, path 
); 
2736     wxDataViewItem 
item( (void*) iter
.user_data 
);; 
2737     event
.SetItem( item 
); 
2738     event
.SetModel( dv
->GetModel() ); 
2739     dv
->GetEventHandler()->ProcessEvent( event 
); 
2743 wxdataview_test_expand_row_callback( GtkTreeView
* treeview
, GtkTreeIter
* iter
, 
2744                                      GtkTreePath 
*path
, wxDataViewCtrl 
*dv 
) 
2746     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING
, dv
->GetId() ); 
2748     wxDataViewItem 
item( (void*) iter
->user_data 
);; 
2749     event
.SetItem( item 
); 
2750     event
.SetModel( dv
->GetModel() ); 
2751     dv
->GetEventHandler()->ProcessEvent( event 
); 
2753     return !event
.IsAllowed(); 
2757 wxdataview_row_expanded_callback( GtkTreeView
* treeview
, GtkTreeIter
* iter
, 
2758                                   GtkTreePath 
*path
, wxDataViewCtrl 
*dv 
) 
2760     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDED
, dv
->GetId() ); 
2762     wxDataViewItem 
item( (void*) iter
->user_data 
);; 
2763     event
.SetItem( item 
); 
2764     event
.SetModel( dv
->GetModel() ); 
2765     dv
->GetEventHandler()->ProcessEvent( event 
); 
2769 wxdataview_test_collapse_row_callback( GtkTreeView
* treeview
, GtkTreeIter
* iter
, 
2770                                        GtkTreePath 
*path
, wxDataViewCtrl 
*dv 
) 
2772     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSING
, dv
->GetId() ); 
2774     wxDataViewItem 
item( (void*) iter
->user_data 
);; 
2775     event
.SetItem( item 
); 
2776     event
.SetModel( dv
->GetModel() ); 
2777     dv
->GetEventHandler()->ProcessEvent( event 
); 
2779     return !event
.IsAllowed(); 
2783 wxdataview_row_collapsed_callback( GtkTreeView
* treeview
, GtkTreeIter
* iter
, 
2784                                    GtkTreePath 
*path
, wxDataViewCtrl 
*dv 
) 
2786     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSED
, dv
->GetId() ); 
2788     wxDataViewItem 
item( (void*) iter
->user_data 
);; 
2789     event
.SetItem( item 
); 
2790     event
.SetModel( dv
->GetModel() ); 
2791     dv
->GetEventHandler()->ProcessEvent( event 
); 
2794 //----------------------------------------------------------------------------- 
2796 //----------------------------------------------------------------------------- 
2798 //----------------------------------------------------------------------------- 
2799 // InsertChild for wxDataViewCtrl 
2800 //----------------------------------------------------------------------------- 
2802 static void wxInsertChildInDataViewCtrl( wxWindowGTK
* parent
, wxWindowGTK
* child 
) 
2804     wxDataViewCtrl 
* dvc 
= (wxDataViewCtrl
*) parent
; 
2805     GtkWidget 
*treeview 
= dvc
->GtkGetTreeView(); 
2807     // Insert widget in GtkTreeView 
2808     if (GTK_WIDGET_REALIZED(treeview
)) 
2809         gtk_widget_set_parent_window( child
->m_widget
, 
2810           gtk_tree_view_get_bin_window( GTK_TREE_VIEW(treeview
) ) ); 
2811     gtk_widget_set_parent( child
->m_widget
, treeview 
); 
2815 void gtk_dataviewctrl_size_callback( GtkWidget 
*WXUNUSED(widget
), 
2816                                      GtkAllocation 
*alloc
, 
2817                                      wxDataViewCtrl 
*win 
) 
2819     wxWindowList::compatibility_iterator node 
= win
->GetChildren().GetFirst(); 
2822         wxWindow 
*child 
= node
->GetData(); 
2825         gtk_widget_size_request( child
->m_widget
, &req 
); 
2827         GtkAllocation alloc
; 
2828         alloc
.x 
= child
->m_x
; 
2829         alloc
.y 
= child
->m_y
; 
2830         alloc
.width 
= child
->m_width
; 
2831         alloc
.height 
= child
->m_height
; 
2832         gtk_widget_size_allocate( child
->m_widget
, &alloc 
); 
2834         node 
= node
->GetNext(); 
2840 IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl
, wxDataViewCtrlBase
) 
2842 wxDataViewCtrl::~wxDataViewCtrl() 
2845         GetModel()->RemoveNotifier( m_notifier 
); 
2847     // remove the model from the GtkTreeView before it gets destroyed by the 
2848     // wxDataViewCtrlBase's dtor 
2849     gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview
), NULL 
); 
2854 void wxDataViewCtrl::Init() 
2859 bool wxDataViewCtrl::Create(wxWindow 
*parent
, wxWindowID id
, 
2860            const wxPoint
& pos
, const wxSize
& size
, 
2861            long style
, const wxValidator
& validator 
) 
2865     if (!PreCreation( parent
, pos
, size 
) || 
2866         !CreateBase( parent
, id
, pos
, size
, style
, validator 
)) 
2868         wxFAIL_MSG( wxT("wxDataViewCtrl creation failed") ); 
2872     m_insertCallback 
= wxInsertChildInDataViewCtrl
; 
2874     m_widget 
= gtk_scrolled_window_new (NULL
, NULL
); 
2876     GtkScrolledWindowSetBorder(m_widget
, style
); 
2878     m_treeview 
= gtk_tree_view_new(); 
2879     gtk_container_add (GTK_CONTAINER (m_widget
), m_treeview
); 
2881     g_signal_connect (m_treeview
, "size_allocate", 
2882                      G_CALLBACK (gtk_dataviewctrl_size_callback
), this); 
2885     if (!gtk_check_version(2,6,0)) 
2886         gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview
), TRUE 
); 
2889     if (style 
& wxDV_MULTIPLE
) 
2891         GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
2892         gtk_tree_selection_set_mode( selection
, GTK_SELECTION_MULTIPLE 
); 
2895     gtk_tree_view_set_headers_visible( GTK_TREE_VIEW(m_treeview
), (style 
& wxDV_NO_HEADER
) == 0 ); 
2898     if (!gtk_check_version(2,10,0)) 
2900         GtkTreeViewGridLines grid 
= GTK_TREE_VIEW_GRID_LINES_NONE
; 
2902         if ((style 
& wxDV_HORIZ_RULES
) != 0 && 
2903             (style 
& wxDV_VERT_RULES
) != 0) 
2904             grid 
= GTK_TREE_VIEW_GRID_LINES_BOTH
; 
2905         else if (style 
& wxDV_VERT_RULES
) 
2906             grid 
= GTK_TREE_VIEW_GRID_LINES_VERTICAL
; 
2907         else if (style 
& wxDV_HORIZ_RULES
) 
2908             grid 
= GTK_TREE_VIEW_GRID_LINES_HORIZONTAL
; 
2910         gtk_tree_view_set_grid_lines( GTK_TREE_VIEW(m_treeview
), grid 
); 
2915         gtk_tree_view_set_rules_hint( GTK_TREE_VIEW(m_treeview
), (style 
& wxDV_HORIZ_RULES
) != 0 ); 
2918     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_widget
), 
2919         GTK_POLICY_AUTOMATIC
, GTK_POLICY_ALWAYS
); 
2920     gtk_widget_show (m_treeview
); 
2922     m_parent
->DoAddChild( this ); 
2926     GtkEnableSelectionEvents(); 
2928     g_signal_connect_after (m_treeview
, "row-activated", 
2929                             G_CALLBACK (wxdataview_row_activated_callback
), this); 
2931     g_signal_connect (m_treeview
, "test-collapse-row", 
2932                             G_CALLBACK (wxdataview_test_collapse_row_callback
), this); 
2934     g_signal_connect_after (m_treeview
, "row-collapsed", 
2935                             G_CALLBACK (wxdataview_row_collapsed_callback
), this); 
2937     g_signal_connect (m_treeview
, "test-expand-row", 
2938                             G_CALLBACK (wxdataview_test_expand_row_callback
), this); 
2940     g_signal_connect_after (m_treeview
, "row-expanded", 
2941                             G_CALLBACK (wxdataview_row_expanded_callback
), this); 
2946 void wxDataViewCtrl::OnInternalIdle() 
2948     wxWindow::OnInternalIdle(); 
2950     unsigned int cols 
= GetColumnCount(); 
2952     for (i 
= 0; i 
< cols
; i
++) 
2954         wxDataViewColumn 
*col 
= GetColumn( i 
); 
2955         col
->OnInternalIdle(); 
2959 bool wxDataViewCtrl::AssociateModel( wxDataViewModel 
*model 
) 
2961     if (!wxDataViewCtrlBase::AssociateModel( model 
)) 
2964     GtkWxTreeModel 
*gtk_model 
= wxgtk_tree_model_new(); 
2965     m_internal 
= new wxDataViewCtrlInternal( this, model
, gtk_model 
); 
2966     gtk_model
->internal 
= m_internal
; 
2968     m_notifier 
= new wxGtkDataViewModelNotifier( gtk_model
, model
, this ); 
2970     model
->AddNotifier( m_notifier 
); 
2972     gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview
), GTK_TREE_MODEL(gtk_model
) ); 
2974     // unref in wxDataViewCtrlInternal 
2975     // g_object_unref( gtk_model ); 
2980 bool wxDataViewCtrl::AppendColumn( wxDataViewColumn 
*col 
) 
2982     if (!wxDataViewCtrlBase::AppendColumn(col
)) 
2985     GtkTreeViewColumn 
*column 
= (GtkTreeViewColumn 
*)col
->GetGtkHandle(); 
2987     gtk_tree_view_append_column( GTK_TREE_VIEW(m_treeview
), column 
); 
2992 wxDataViewItem 
wxDataViewCtrl::GetSelection() 
2994     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
2996     if (m_windowStyle 
& wxDV_MULTIPLE
) 
2998         // Report the first one 
2999         GtkTreeModel 
*model
; 
3000         GList 
*list 
= gtk_tree_selection_get_selected_rows( selection
, &model 
); 
3004             GtkTreePath 
*path 
= (GtkTreePath
*) list
->data
; 
3006             m_internal
->get_iter( &iter
, path 
); 
3009             g_list_foreach( list
, (GFunc
) gtk_tree_path_free
, NULL 
); 
3010             g_list_free( list 
); 
3012             return wxDataViewItem( (void*) iter
.user_data 
); 
3018         if (gtk_tree_selection_get_selected( selection
, NULL
, &iter 
)) 
3020             wxDataViewItem 
item( (void*) iter
.user_data 
); 
3025     return wxDataViewItem(0); 
3028 int wxDataViewCtrl::GetSelections( wxDataViewItemArray 
& sel 
) const 
3032     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
3033     if (HasFlag(wxDV_MULTIPLE
)) 
3035         GtkTreeModel 
*model
; 
3036         GList 
*list 
= gtk_tree_selection_get_selected_rows( selection
, &model 
); 
3041             GtkTreePath 
*path 
= (GtkTreePath
*) list
->data
; 
3044             m_internal
->get_iter( &iter
, path 
); 
3046             sel
.Add( wxDataViewItem( (void*) iter
.user_data 
) ); 
3048             list 
= g_list_next( list 
); 
3053         g_list_foreach( list
, (GFunc
) gtk_tree_path_free
, NULL 
); 
3054         g_list_free( list 
); 
3060         GtkTreeModel 
*model
; 
3062         gboolean has_selection 
= gtk_tree_selection_get_selected( selection
, &model
, &iter 
); 
3065             sel
.Add( wxDataViewItem( (void*) iter
.user_data
) ); 
3073 void wxDataViewCtrl::SetSelections( const wxDataViewItemArray 
& sel 
) 
3075     GtkDisableSelectionEvents(); 
3077     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
3079     gtk_tree_selection_unselect_all( selection 
); 
3082     for (i 
= 0; i 
< sel
.GetCount(); i
++) 
3085         iter
.user_data 
= (gpointer
) sel
[i
].GetID(); 
3086         gtk_tree_selection_select_iter( selection
, &iter 
); 
3089     GtkEnableSelectionEvents(); 
3092 void wxDataViewCtrl::Select( const wxDataViewItem 
& item 
) 
3094     GtkDisableSelectionEvents(); 
3096     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
3099     iter
.user_data 
= (gpointer
) item
.GetID(); 
3100     gtk_tree_selection_select_iter( selection
, &iter 
); 
3102     GtkEnableSelectionEvents(); 
3105 void wxDataViewCtrl::Unselect( const wxDataViewItem 
& item 
) 
3107     GtkDisableSelectionEvents(); 
3109     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
3112     iter
.user_data 
= (gpointer
) item
.GetID(); 
3113     gtk_tree_selection_unselect_iter( selection
, &iter 
); 
3115     GtkEnableSelectionEvents(); 
3118 bool wxDataViewCtrl::IsSelected( const wxDataViewItem 
& item 
) const 
3120     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
3123     iter
.user_data 
= (gpointer
) item
.GetID(); 
3125     return gtk_tree_selection_iter_is_selected( selection
, &iter 
); 
3128 void wxDataViewCtrl::SelectAll() 
3130     GtkDisableSelectionEvents(); 
3132     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
3134     gtk_tree_selection_select_all( selection 
); 
3136     GtkEnableSelectionEvents(); 
3139 void wxDataViewCtrl::UnselectAll() 
3141     GtkDisableSelectionEvents(); 
3143     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
3145     gtk_tree_selection_unselect_all( selection 
); 
3147     GtkEnableSelectionEvents(); 
3150 void wxDataViewCtrl::EnsureVisible( const wxDataViewItem 
& item
, wxDataViewColumn 
*column 
) 
3153     iter
.user_data 
= (gpointer
) item
.GetID(); 
3154     GtkTreePath 
*path 
= m_internal
->get_path( &iter 
); 
3155     gtk_tree_view_scroll_to_cell( GTK_TREE_VIEW(m_treeview
), path
, NULL
, false, 0.0, 0.0 ); 
3156     gtk_tree_path_free( path 
); 
3159 void wxDataViewCtrl::HitTest( const wxPoint 
&point
,  
3160                           wxDataViewItem 
&item
, unsigned int &column 
) const 
3162     item 
= wxDataViewItem(0); 
3166 wxRect 
wxDataViewCtrl::GetItemRect( const wxDataViewItem 
&item
,  
3167                           unsigned int column 
) const 
3172 void wxDataViewCtrl::DoSetExpanderColumn() 
3176 void wxDataViewCtrl::DoSetIndent() 
3180 void wxDataViewCtrl::GtkDisableSelectionEvents() 
3182     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
3183     g_signal_handlers_disconnect_by_func( selection
, 
3184                             (gpointer
) (wxdataview_selection_changed_callback
), this); 
3187 void wxDataViewCtrl::GtkEnableSelectionEvents() 
3189     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
3190     g_signal_connect_after (selection
, "changed", 
3191                             G_CALLBACK (wxdataview_selection_changed_callback
), this); 
3196 wxDataViewCtrl::GetClassDefaultAttributes(wxWindowVariant 
WXUNUSED(variant
)) 
3198     return GetDefaultAttributesFromGTKWidget(gtk_tree_view_new
); 
3203     // !wxUSE_GENERICDATAVIEWCTRL 
3206     // wxUSE_DATAVIEWCTRL