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" 
  29 #include "wx/gtk/private.h" 
  30 #include "wx/gtk/win_gtk.h" 
  32 #include <gobject/gvaluecollector.h> 
  33 #include <gtk/gtktreemodel.h> 
  34 #include <gtk/gtktreednd.h> 
  36 #include <gdk/gdkkeysyms.h> 
  38 //----------------------------------------------------------------------------- 
  40 //----------------------------------------------------------------------------- 
  44 //----------------------------------------------------------------------------- 
  46 //----------------------------------------------------------------------------- 
  48 extern bool   g_blockEventsOnDrag
; 
  50 //----------------------------------------------------------------------------- 
  51 // define new GTK+ class wxGtkListStore 
  52 //----------------------------------------------------------------------------- 
  56 #define GTK_TYPE_WX_LIST_STORE               (gtk_wx_list_store_get_type ()) 
  57 #define GTK_WX_LIST_STORE(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_LIST_STORE, GtkWxListStore)) 
  58 #define GTK_WX_LIST_STORE_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_LIST_STORE, GtkWxListStoreClass)) 
  59 #define GTK_IS_WX_LIST_STORE(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_LIST_STORE)) 
  60 #define GTK_IS_WX_LIST_STORE_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_LIST_STORE)) 
  61 #define GTK_WX_LIST_STORE_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_LIST_STORE, GtkWxListStoreClass)) 
  63 GType         
gtk_wx_list_store_get_type         (void); 
  65 typedef struct _GtkWxListStore       GtkWxListStore
; 
  66 typedef struct _GtkWxListStoreClass  GtkWxListStoreClass
; 
  68 struct _GtkWxListStore
 
  74   wxDataViewListModel 
*model
; 
  77 struct _GtkWxListStoreClass
 
  79   GObjectClass list_parent_class
; 
  82 static GtkWxListStore 
*wxgtk_list_store_new          (void); 
  83 static void         wxgtk_list_store_init            (GtkWxListStore      
*list_store
); 
  84 static void         wxgtk_list_store_class_init      (GtkWxListStoreClass 
*klass
); 
  85 static void         wxgtk_list_store_tree_model_init (GtkTreeModelIface 
*iface
); 
  86 static void         wxgtk_list_store_finalize        (GObject           
*object
); 
  87 static GtkTreeModelFlags 
wxgtk_list_store_get_flags  (GtkTreeModel      
*tree_model
); 
  88 static gint         
wxgtk_list_store_get_n_columns   (GtkTreeModel      
*tree_model
); 
  89 static GType        
wxgtk_list_store_get_column_type (GtkTreeModel      
*tree_model
, 
  91 static gboolean     
wxgtk_list_store_get_iter        (GtkTreeModel      
*tree_model
, 
  94 static GtkTreePath 
*wxgtk_list_store_get_path        (GtkTreeModel      
*tree_model
, 
  96 static void         wxgtk_list_store_get_value       (GtkTreeModel      
*tree_model
, 
 100 static gboolean     
wxgtk_list_store_iter_next       (GtkTreeModel      
*tree_model
, 
 102 static gboolean     
wxgtk_list_store_iter_children   (GtkTreeModel      
*tree_model
, 
 104                                                       GtkTreeIter       
*parent
); 
 105 static gboolean     
wxgtk_list_store_iter_has_child  (GtkTreeModel      
*tree_model
, 
 107 static gint         
wxgtk_list_store_iter_n_children (GtkTreeModel      
*tree_model
, 
 109 static gboolean     
wxgtk_list_store_iter_nth_child  (GtkTreeModel      
*tree_model
, 
 113 static gboolean     
wxgtk_list_store_iter_parent     (GtkTreeModel      
*tree_model
, 
 117 static GObjectClass 
*list_parent_class 
= NULL
; 
 120 gtk_wx_list_store_get_type (void) 
 122     static GType list_store_type 
= 0; 
 124     if (!list_store_type
) 
 126         static const GTypeInfo list_store_info 
= 
 128             sizeof (GtkWxListStoreClass
), 
 129             NULL
,   /* base_init */ 
 130             NULL
,   /* base_finalize */ 
 131             (GClassInitFunc
) wxgtk_list_store_class_init
, 
 132             NULL
,   /* class_finalize */ 
 133             NULL
,   /* class_data */ 
 134             sizeof (GtkWxListStore
), 
 136             (GInstanceInitFunc
) wxgtk_list_store_init
, 
 139       static const GInterfaceInfo tree_model_info 
= 
 141           (GInterfaceInitFunc
) wxgtk_list_store_tree_model_init
, 
 146       list_store_type 
= g_type_register_static (G_TYPE_OBJECT
, "GtkWxListStore", 
 147                                                 &list_store_info
, (GTypeFlags
)0 ); 
 149       g_type_add_interface_static (list_store_type
, 
 154   return list_store_type
; 
 157 static GtkWxListStore 
* 
 158 wxgtk_list_store_new(void) 
 160     GtkWxListStore 
*retval 
= (GtkWxListStore 
*) g_object_new (GTK_TYPE_WX_LIST_STORE
, NULL
); 
 165 wxgtk_list_store_class_init (GtkWxListStoreClass 
*klass
) 
 167     list_parent_class 
= (GObjectClass
*) g_type_class_peek_parent (klass
); 
 168     GObjectClass 
*object_class 
= (GObjectClass
*) klass
; 
 169     object_class
->finalize 
= wxgtk_list_store_finalize
; 
 173 wxgtk_list_store_tree_model_init (GtkTreeModelIface 
*iface
) 
 175     iface
->get_flags 
= wxgtk_list_store_get_flags
; 
 176     iface
->get_n_columns 
= wxgtk_list_store_get_n_columns
; 
 177     iface
->get_column_type 
= wxgtk_list_store_get_column_type
; 
 178     iface
->get_iter 
= wxgtk_list_store_get_iter
; 
 179     iface
->get_path 
= wxgtk_list_store_get_path
; 
 180     iface
->get_value 
= wxgtk_list_store_get_value
; 
 181     iface
->iter_next 
= wxgtk_list_store_iter_next
; 
 182     iface
->iter_children 
= wxgtk_list_store_iter_children
; 
 183     iface
->iter_has_child 
= wxgtk_list_store_iter_has_child
; 
 184     iface
->iter_n_children 
= wxgtk_list_store_iter_n_children
; 
 185     iface
->iter_nth_child 
= wxgtk_list_store_iter_nth_child
; 
 186     iface
->iter_parent 
= wxgtk_list_store_iter_parent
; 
 190 wxgtk_list_store_init (GtkWxListStore 
*list_store
) 
 192     list_store
->model 
= NULL
; 
 193     list_store
->stamp 
= g_random_int(); 
 197 wxgtk_list_store_finalize (GObject 
*object
) 
 199     /* GtkWxListStore *list_store = GTK_WX_LIST_STORE (object); */ 
 201     /* we need to sort out, which class deletes what */ 
 202     /* delete list_store->model; */ 
 205     (* list_parent_class
->finalize
) (object
); 
 210 //----------------------------------------------------------------------------- 
 211 // implement callbacks from wxGtkListStore class by letting 
 212 // them call the methods of wxWidgets' wxDataViewListModel 
 213 //----------------------------------------------------------------------------- 
 215 static GtkTreeModelFlags
 
 216 wxgtk_list_store_get_flags (GtkTreeModel 
*tree_model
) 
 218     g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), (GtkTreeModelFlags
)0 ); 
 220     // GTK+ list store uses a linked list for storing the 
 221     // items and a pointer to a child is used as the member 
 222     // field of a GtkTreeIter. This means that the iter is 
 223     // valid in the GtkListStore as long as the child exists. 
 224     // We use the index of the row and since the index of a 
 225     // specific row will change if a row above is deleted, 
 226     // the iter does not persist 
 227     return /* GTK_TREE_MODEL_ITERS_PERSIST | */ GTK_TREE_MODEL_LIST_ONLY
; 
 231 wxgtk_list_store_get_n_columns (GtkTreeModel 
*tree_model
) 
 233     GtkWxListStore 
*list_store 
= (GtkWxListStore 
*) tree_model
; 
 234     g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), 0); 
 236     return list_store
->model
->GetNumberOfCols(); 
 240 wxgtk_list_store_get_column_type (GtkTreeModel 
*tree_model
, 
 243     GtkWxListStore 
*list_store 
= (GtkWxListStore 
*) tree_model
; 
 244     g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), G_TYPE_INVALID
); 
 246     GType gtype 
= G_TYPE_INVALID
; 
 248     wxString wxtype 
= list_store
->model
->GetColType( (size_t) index 
); 
 250     if (wxtype 
== wxT("string")) 
 251         gtype 
= G_TYPE_STRING
; 
 257 wxgtk_list_store_get_iter (GtkTreeModel 
*tree_model
, 
 261     GtkWxListStore 
*list_store 
= (GtkWxListStore 
*) tree_model
; 
 262     g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), FALSE
); 
 263     g_return_val_if_fail (gtk_tree_path_get_depth (path
) > 0, FALSE
); 
 265     size_t i 
= (size_t)gtk_tree_path_get_indices (path
)[0]; 
 267     if (i 
>= list_store
->model
->GetNumberOfRows()) 
 270     iter
->stamp 
= list_store
->stamp
; 
 271     // user_data is just the index 
 272     iter
->user_data 
= (gpointer
) i
; 
 278 wxgtk_list_store_get_path (GtkTreeModel 
*tree_model
, 
 281     g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), NULL
); 
 282     g_return_val_if_fail (iter
->stamp 
== GTK_WX_LIST_STORE (tree_model
)->stamp
, NULL
); 
 284     GtkTreePath 
*retval 
= gtk_tree_path_new (); 
 285     // user_data is just the index 
 286     int i 
= (wxUIntPtr
) iter
->user_data
; 
 287     gtk_tree_path_append_index (retval
, i
); 
 292 wxgtk_list_store_get_value (GtkTreeModel 
*tree_model
, 
 297     GtkWxListStore 
*list_store 
= (GtkWxListStore 
*) tree_model
; 
 298     g_return_if_fail (GTK_IS_WX_LIST_STORE (tree_model
) ); 
 300     wxDataViewListModel 
*model 
= list_store
->model
; 
 301     wxString mtype 
= model
->GetColType( (size_t) column 
); 
 302     if (mtype 
== wxT("string")) 
 305         g_value_init( value
, G_TYPE_STRING 
); 
 306         model
->GetValue( variant
, (size_t) column
, (size_t) iter
->user_data 
); 
 307         g_value_set_string( value
, wxGTK_CONV(variant
.GetString()) ); 
 314   GtkTreeDataList 
*list
; 
 315   gint tmp_column 
= column
; 
 317   g_return_if_fail (column 
< GTK_LIST_STORE (tree_model
)->n_columns
); 
 318   g_return_if_fail (GTK_LIST_STORE (tree_model
)->stamp 
== iter
->stamp
); 
 320   list 
= G_SLIST (iter
->user_data
)->data
; 
 322   while (tmp_column
-- > 0 && list
) 
 326     g_value_init (value
, GTK_LIST_STORE (tree_model
)->column_headers
[column
]); 
 328     _gtk_tree_data_list_node_to_value (list
, 
 329                                        GTK_LIST_STORE (tree_model
)->column_headers
[column
], 
 336 wxgtk_list_store_iter_next (GtkTreeModel  
*tree_model
, 
 339     g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), FALSE
); 
 340     GtkWxListStore 
*list_store 
= (GtkWxListStore 
*) tree_model
; 
 342     g_return_val_if_fail (list_store
->stamp 
== iter
->stamp
, FALSE
); 
 344     int n 
= (wxUIntPtr
) iter
->user_data
; 
 349     if (n 
>= (int) list_store
->model
->GetNumberOfRows()-1) 
 352     iter
->user_data 
= (gpointer
) ++n
; 
 358 wxgtk_list_store_iter_children (GtkTreeModel 
*tree_model
, 
 362     g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), FALSE
); 
 363     GtkWxListStore 
*list_store 
= (GtkWxListStore 
*) tree_model
; 
 365     // this is a list, nodes have no children 
 369     iter
->stamp 
= list_store
->stamp
; 
 370     iter
->user_data 
= (gpointer
) -1; 
 376 wxgtk_list_store_iter_has_child (GtkTreeModel 
*tree_model
, 
 383 wxgtk_list_store_iter_n_children (GtkTreeModel 
*tree_model
, 
 386     g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), -1); 
 387     GtkWxListStore 
*list_store 
= (GtkWxListStore 
*) tree_model
; 
 390         return (gint
) list_store
->model
->GetNumberOfRows(); 
 392     g_return_val_if_fail (list_store
->stamp 
== iter
->stamp
, -1); 
 398 wxgtk_list_store_iter_nth_child (GtkTreeModel 
*tree_model
, 
 403     g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), FALSE
); 
 404     GtkWxListStore 
*list_store 
= (GtkWxListStore 
*) tree_model
; 
 412     if (n 
>= (gint
) list_store
->model
->GetNumberOfRows()) 
 415     iter
->stamp 
= list_store
->stamp
; 
 416     iter
->user_data 
= (gpointer
) n
; 
 422 wxgtk_list_store_iter_parent (GtkTreeModel 
*tree_model
, 
 429 //----------------------------------------------------------------------------- 
 430 // define new GTK+ class wxGtkCellRenderer 
 431 //----------------------------------------------------------------------------- 
 435 #define GTK_TYPE_WX_CELL_RENDERER               (gtk_wx_cell_renderer_get_type ()) 
 436 #define GTK_WX_CELL_RENDERER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRenderer)) 
 437 #define GTK_WX_CELL_RENDERER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRendererClass)) 
 438 #define GTK_IS_WX_CELL_RENDERER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_CELL_RENDERER)) 
 439 #define GTK_IS_WX_CELL_RENDERER_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_CELL_RENDERER)) 
 440 #define GTK_WX_CELL_RENDERER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRendererClass)) 
 442 GType            
gtk_wx_cell_renderer_get_type (void); 
 444 typedef struct _GtkWxCellRenderer GtkWxCellRenderer
; 
 445 typedef struct _GtkWxCellRendererClass GtkWxCellRendererClass
; 
 447 struct _GtkWxCellRenderer
 
 449   GtkCellRenderer parent
; 
 452   wxDataViewCustomCell 
*cell
; 
 456 struct _GtkWxCellRendererClass
 
 458   GtkCellRendererClass cell_parent_class
; 
 462 static GtkCellRenderer 
*gtk_wx_cell_renderer_new   (void); 
 463 static void gtk_wx_cell_renderer_init ( 
 464                         GtkWxCellRenderer      
*cell 
); 
 465 static void gtk_wx_cell_renderer_class_init( 
 466                         GtkWxCellRendererClass 
*klass 
); 
 467 static void gtk_wx_cell_renderer_finalize ( 
 469 static void gtk_wx_cell_renderer_get_size ( 
 470                         GtkCellRenderer         
*cell
, 
 472                         GdkRectangle            
*rectangle
, 
 477 static void gtk_wx_cell_renderer_render ( 
 478                         GtkCellRenderer         
*cell
, 
 481                         GdkRectangle            
*background_area
, 
 482                         GdkRectangle            
*cell_area
, 
 483                         GdkRectangle            
*expose_area
, 
 484                         GtkCellRendererState     flags 
); 
 485 static gboolean 
gtk_wx_cell_renderer_activate( 
 486                         GtkCellRenderer         
*cell
, 
 490                         GdkRectangle            
*background_area
, 
 491                         GdkRectangle            
*cell_area
, 
 492                         GtkCellRendererState     flags 
); 
 494 static GObjectClass 
*cell_parent_class 
= NULL
; 
 499 gtk_wx_cell_renderer_get_type (void) 
 501     static GType cell_wx_type 
= 0; 
 505         static const GTypeInfo cell_wx_info 
= 
 507             sizeof (GtkWxCellRendererClass
), 
 508             NULL
, /* base_init */ 
 509             NULL
, /* base_finalize */ 
 510             (GClassInitFunc
) gtk_wx_cell_renderer_class_init
, 
 511             NULL
, /* class_finalize */ 
 512             NULL
, /* class_data */ 
 513             sizeof (GtkWxCellRenderer
), 
 515             (GInstanceInitFunc
) gtk_wx_cell_renderer_init
, 
 518         cell_wx_type 
= g_type_register_static( GTK_TYPE_CELL_RENDERER
, 
 519             "GtkWxCellRenderer", &cell_wx_info
, (GTypeFlags
)0 ); 
 526 gtk_wx_cell_renderer_init (GtkWxCellRenderer 
*cell
) 
 529     cell
->last_click 
= 0; 
 533 gtk_wx_cell_renderer_class_init (GtkWxCellRendererClass 
*klass
) 
 535     GObjectClass 
*object_class 
= G_OBJECT_CLASS (klass
); 
 536     GtkCellRendererClass 
*cell_class 
= GTK_CELL_RENDERER_CLASS (klass
); 
 538     cell_parent_class 
= (GObjectClass
*) g_type_class_peek_parent (klass
); 
 540     object_class
->finalize 
= gtk_wx_cell_renderer_finalize
; 
 542     cell_class
->get_size 
= gtk_wx_cell_renderer_get_size
; 
 543     cell_class
->render 
= gtk_wx_cell_renderer_render
; 
 544     cell_class
->activate 
= gtk_wx_cell_renderer_activate
; 
 548 gtk_wx_cell_renderer_finalize (GObject 
*object
) 
 551     (* G_OBJECT_CLASS (cell_parent_class
)->finalize
) (object
); 
 555 gtk_wx_cell_renderer_new (void) 
 557     return (GtkCellRenderer
*) g_object_new (GTK_TYPE_WX_CELL_RENDERER
, NULL
); 
 561 gtk_wx_cell_renderer_get_size (GtkCellRenderer 
*renderer
, 
 563                                GdkRectangle    
*cell_area
, 
 569     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
 570     wxDataViewCustomCell 
*cell 
= wxrenderer
->cell
; 
 572     wxSize size 
= cell
->GetSize(); 
 574     gint calc_width  
= (gint
) renderer
->xpad 
* 2 + size
.x
; 
 575     gint calc_height 
= (gint
) renderer
->ypad 
* 2 + size
.y
; 
 582     if (cell_area 
&& size
.x 
> 0 && size
.y 
> 0) 
 586             *x_offset 
= (gint
)((renderer
->xalign 
* 
 587                                (cell_area
->width 
- calc_width 
- 2 * renderer
->xpad
))); 
 588             *x_offset 
= MAX (*x_offset
, 0) + renderer
->xpad
; 
 592             *y_offset 
= (gint
)((renderer
->yalign 
* 
 593                                (cell_area
->height 
- calc_height 
- 2 * renderer
->ypad
))); 
 594             *y_offset 
= MAX (*y_offset
, 0) + renderer
->ypad
; 
 602         *height 
= calc_height
; 
 606 gtk_wx_cell_renderer_render (GtkCellRenderer      
*renderer
, 
 609                              GdkRectangle         
*background_area
, 
 610                              GdkRectangle         
*cell_area
, 
 611                              GdkRectangle         
*expose_area
, 
 612                              GtkCellRendererState  flags
) 
 615     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
 616     wxDataViewCustomCell 
*cell 
= wxrenderer
->cell
; 
 619     gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
, 
 625     rect
.x 
+= cell_area
->x
; 
 626     rect
.y 
+= cell_area
->y
; 
 627     rect
.width  
-= renderer
->xpad 
* 2; 
 628     rect
.height 
-= renderer
->ypad 
* 2; 
 631     if (gdk_rectangle_intersect (expose_area
, &rect
, &dummy
)) 
 633         wxRect 
renderrect( rect
.x
, rect
.y
, rect
.width
, rect
.height 
); 
 634         wxWindowDC
* dc 
= (wxWindowDC
*) cell
->GetDC(); 
 635         if (dc
->m_window 
== NULL
) 
 637             dc
->m_window 
= window
; 
 642         if (flags 
& GTK_CELL_RENDERER_SELECTED
) 
 643             state 
|= wxDATAVIEW_CELL_SELECTED
; 
 644         if (flags 
& GTK_CELL_RENDERER_PRELIT
) 
 645             state 
|= wxDATAVIEW_CELL_PRELIT
; 
 646         if (flags 
& GTK_CELL_RENDERER_INSENSITIVE
) 
 647             state 
|= wxDATAVIEW_CELL_INSENSITIVE
; 
 648         if (flags 
& GTK_CELL_RENDERER_INSENSITIVE
) 
 649             state 
|= wxDATAVIEW_CELL_INSENSITIVE
; 
 650         if (flags 
& GTK_CELL_RENDERER_FOCUSED
) 
 651             state 
|= wxDATAVIEW_CELL_FOCUSED
; 
 652         cell
->Render( renderrect
, dc
, state 
); 
 657 gtk_wx_cell_renderer_activate( 
 658                         GtkCellRenderer         
*renderer
, 
 662                         GdkRectangle            
*background_area
, 
 663                         GdkRectangle            
*cell_area
, 
 664                         GtkCellRendererState     flags 
) 
 666     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
 667     wxDataViewCustomCell 
*cell 
= wxrenderer
->cell
; 
 670     gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
, 
 676     rect
.x 
+= cell_area
->x
; 
 677     rect
.y 
+= cell_area
->y
; 
 678     rect
.width  
-= renderer
->xpad 
* 2; 
 679     rect
.height 
-= renderer
->ypad 
* 2; 
 681     wxRect 
renderrect( rect
.x
, rect
.y
, rect
.width
, rect
.height 
); 
 683     wxDataViewListModel 
*model 
= cell
->GetOwner()->GetOwner()->GetModel(); 
 685     GtkTreePath 
*treepath 
= gtk_tree_path_new_from_string( path 
); 
 686     size_t model_row 
= (size_t)gtk_tree_path_get_indices (treepath
)[0]; 
 687     gtk_tree_path_free( treepath 
); 
 689     size_t model_col 
= cell
->GetOwner()->GetModelColumn(); 
 691     if (event
->type 
== GDK_BUTTON_PRESS
) 
 693         GdkEventButton 
*button_event 
= (GdkEventButton
*) event
; 
 694         wxPoint 
pt( ((int) button_event
->x
) - renderrect
.x
, 
 695                     ((int) button_event
->y
) - renderrect
.y 
); 
 698         if (button_event
->button 
== 1) 
 700             if (cell
->LeftClick( pt
, renderrect
, model
, model_col
, model_row 
)) 
 702             // TODO: query system double-click time 
 703             if (button_event
->time 
- wxrenderer
->last_click 
< 400) 
 704                 if (cell
->Activate( renderrect
, model
, model_col
, model_row 
)) 
 707         if (button_event
->button 
== 3) 
 709             if (cell
->RightClick( pt
, renderrect
, model
, model_col
, model_row 
)) 
 713         wxrenderer
->last_click 
= button_event
->time
; 
 721 // --------------------------------------------------------- 
 722 // wxGtkDataViewListModelNotifier 
 723 // --------------------------------------------------------- 
 725 class wxGtkDataViewListModelNotifier
: public wxDataViewListModelNotifier
 
 728     wxGtkDataViewListModelNotifier( GtkWxListStore
* gtk_store
, wxDataViewListModel 
*wx_model 
); 
 730     virtual bool RowAppended(); 
 731     virtual bool RowPrepended(); 
 732     virtual bool RowInserted( size_t before 
); 
 733     virtual bool RowDeleted( size_t row 
); 
 734     virtual bool RowChanged( size_t row 
); 
 735     virtual bool ValueChanged( size_t col
, size_t row 
); 
 736     virtual bool RowsReordered( size_t *new_order 
); 
 737     virtual bool Cleared(); 
 739     GtkWxListStore      
*m_gtk_store
; 
 740     wxDataViewListModel 
*m_wx_model
; 
 743 // --------------------------------------------------------- 
 744 // wxGtkDataViewListModelNotifier 
 745 // --------------------------------------------------------- 
 747 wxGtkDataViewListModelNotifier::wxGtkDataViewListModelNotifier( 
 748     GtkWxListStore
* gtk_store
, wxDataViewListModel 
*wx_model 
) 
 750     m_gtk_store 
= gtk_store
; 
 751     m_wx_model 
= wx_model
; 
 754 bool wxGtkDataViewListModelNotifier::RowAppended() 
 756     size_t pos 
= m_wx_model
->GetNumberOfRows()-1; 
 759     iter
.stamp 
= m_gtk_store
->stamp
; 
 760     iter
.user_data 
= (gpointer
) pos
; 
 762     GtkTreePath 
*path 
= gtk_tree_path_new (); 
 763     gtk_tree_path_append_index (path
, (gint
) pos
); 
 764     gtk_tree_model_row_inserted (GTK_TREE_MODEL (m_gtk_store
), path
, &iter
); 
 765     gtk_tree_path_free (path
); 
 770 bool wxGtkDataViewListModelNotifier::RowPrepended() 
 773     iter
.stamp 
= m_gtk_store
->stamp
; 
 774     iter
.user_data 
= (gpointer
) 0; 
 776     GtkTreePath 
*path 
= gtk_tree_path_new (); 
 777     gtk_tree_path_append_index (path
, (gint
) 0); 
 778     gtk_tree_model_row_inserted (GTK_TREE_MODEL (m_gtk_store
), path
, &iter
); 
 779     gtk_tree_path_free (path
); 
 784 bool wxGtkDataViewListModelNotifier::RowInserted( size_t before 
) 
 789 bool wxGtkDataViewListModelNotifier::RowDeleted( size_t row 
) 
 794 bool wxGtkDataViewListModelNotifier::RowChanged( size_t row 
) 
 797     iter
.stamp 
= m_gtk_store
->stamp
; 
 798     iter
.user_data 
= (gpointer
) row
; 
 799     GtkTreePath 
*path 
= gtk_tree_model_get_path (GTK_TREE_MODEL (m_gtk_store
), &iter
); 
 800     gtk_tree_model_row_changed (GTK_TREE_MODEL (m_gtk_store
), path
, &iter
); 
 801     gtk_tree_path_free (path
); 
 806 bool wxGtkDataViewListModelNotifier::ValueChanged( size_t model_col
, size_t model_row 
) 
 808     // This adds GTK+'s missing MVC logic for ValueChanged 
 809     wxNode 
*node 
= GetOwner()->m_viewingColumns
.GetFirst(); 
 812         wxDataViewViewingColumn
* viewing_column 
= (wxDataViewViewingColumn
*) node
->GetData(); 
 813         if (viewing_column
->m_modelColumn 
== model_col
) 
 815             GtkTreeView 
*widget 
= GTK_TREE_VIEW(viewing_column
->m_viewColumn
->GetOwner()->m_treeview
); 
 816             GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(viewing_column
->m_viewColumn
->GetGtkHandle()); 
 819             GtkTreePath 
*path 
= gtk_tree_path_new(); 
 820             gtk_tree_path_append_index( path
, model_row 
); 
 821             GdkRectangle cell_area
; 
 822             gtk_tree_view_get_cell_area( widget
, path
, column
, &cell_area 
); 
 823             gtk_tree_path_free( path 
); 
 825             int ydiff 
= column
->button
->allocation
.height
; 
 827             gtk_widget_queue_draw_area( GTK_WIDGET(widget
), 
 828                 cell_area
.x
, ydiff 
+ cell_area
.y
, cell_area
.width
, cell_area
.height 
); 
 831         node 
= node
->GetNext(); 
 837 bool wxGtkDataViewListModelNotifier::RowsReordered( size_t *new_order 
) 
 839     // Assume sizeof(size_t)= == sizeof(gint) 
 841     GtkTreePath 
*path 
= gtk_tree_path_new (); 
 842     gtk_tree_model_rows_reordered (GTK_TREE_MODEL (m_gtk_store
), path
, NULL
, (gint
*)new_order
); 
 843     gtk_tree_path_free (path
); 
 845     // This adds GTK+'s missing MVC logic for RowsReordered 
 846     wxNode 
*node 
= GetOwner()->m_viewingColumns
.GetFirst(); 
 849         wxDataViewViewingColumn
* viewing_column 
= (wxDataViewViewingColumn
*) node
->GetData(); 
 850         GtkTreeView 
*widget 
= GTK_TREE_VIEW(viewing_column
->m_viewColumn
->GetOwner()->m_treeview
); 
 851         // Doesn't work yet... 
 852         gtk_widget_queue_draw( GTK_WIDGET(widget
) ); 
 854         node 
= node
->GetNext(); 
 860 bool wxGtkDataViewListModelNotifier::Cleared() 
 865 // --------------------------------------------------------- 
 867 // --------------------------------------------------------- 
 869 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCell
, wxDataViewCellBase
) 
 871 wxDataViewCell::wxDataViewCell( const wxString 
&varianttype
, wxDataViewCellMode mode 
) : 
 872     wxDataViewCellBase( varianttype
, mode 
) 
 877 // --------------------------------------------------------- 
 878 // wxDataViewTextCell 
 879 // --------------------------------------------------------- 
 882 static void wxGtkTextRendererEditedCallback( GtkCellRendererText 
*renderer
, 
 883     gchar 
*arg1
, gchar 
*arg2
, gpointer user_data 
); 
 886 static void wxGtkTextRendererEditedCallback( GtkCellRendererText 
*renderer
, 
 887     gchar 
*arg1
, gchar 
*arg2
, gpointer user_data 
) 
 889     wxDataViewTextCell 
*cell 
= (wxDataViewTextCell
*) user_data
; 
 891     wxString tmp 
= wxGTK_CONV_BACK( arg2 
); 
 892     wxVariant value 
= tmp
; 
 893     if (!cell
->Validate( value 
)) 
 896     wxDataViewListModel 
*model 
= cell
->GetOwner()->GetOwner()->GetModel(); 
 898     GtkTreePath 
*path 
= gtk_tree_path_new_from_string( arg1 
); 
 899     size_t model_row 
= (size_t)gtk_tree_path_get_indices (path
)[0]; 
 900     gtk_tree_path_free( path 
); 
 902     size_t model_col 
= cell
->GetOwner()->GetModelColumn(); 
 904     model
->SetValue( value
, model_col
, model_row 
); 
 905     model
->ValueChanged( model_col
, model_row 
); 
 908 IMPLEMENT_ABSTRACT_CLASS(wxDataViewTextCell
, wxDataViewCell
) 
 910 wxDataViewTextCell::wxDataViewTextCell( const wxString 
&varianttype
, wxDataViewCellMode mode 
) : 
 911     wxDataViewCell( varianttype
, mode 
) 
 913     m_renderer 
= (void*) gtk_cell_renderer_text_new(); 
 915     if (m_mode 
& wxDATAVIEW_CELL_EDITABLE
) 
 917         GValue gvalue 
= { 0, }; 
 918         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
 919         g_value_set_boolean( &gvalue
, true ); 
 920         g_object_set_property( G_OBJECT(m_renderer
), "editable", &gvalue 
); 
 921         g_value_unset( &gvalue 
); 
 923         g_signal_connect_after( m_renderer
, "edited", G_CALLBACK(wxGtkTextRendererEditedCallback
), this ); 
 927 bool wxDataViewTextCell::SetValue( const wxVariant 
&value 
) 
 929     wxString tmp 
= value
; 
 931     GValue gvalue 
= { 0, }; 
 932     g_value_init( &gvalue
, G_TYPE_STRING 
); 
 933     g_value_set_string( &gvalue
, wxGTK_CONV( tmp 
) ); 
 934     g_object_set_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
 935     g_value_unset( &gvalue 
); 
 940 bool wxDataViewTextCell::GetValue( wxVariant 
&value 
) 
 942     GValue gvalue 
= { 0, }; 
 943     g_value_init( &gvalue
, G_TYPE_STRING 
); 
 944     g_object_get_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
 945     wxString tmp 
= wxGTK_CONV_BACK( g_value_get_string( &gvalue 
) ); 
 946     g_value_unset( &gvalue 
); 
 953 // --------------------------------------------------------- 
 954 // wxDataViewToggleCell 
 955 // --------------------------------------------------------- 
 958 static void wxGtkToggleRendererToggledCallback( GtkCellRendererToggle 
*renderer
, 
 959     gchar 
*path
, gpointer user_data 
); 
 962 static void wxGtkToggleRendererToggledCallback( GtkCellRendererToggle 
*renderer
, 
 963     gchar 
*path
, gpointer user_data 
) 
 965     wxDataViewToggleCell 
*cell 
= (wxDataViewToggleCell
*) user_data
; 
 968     GValue gvalue 
= { 0, }; 
 969     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
 970     g_object_get_property( G_OBJECT(renderer
), "active", &gvalue 
); 
 971     bool tmp 
= g_value_get_boolean( &gvalue 
); 
 972     g_value_unset( &gvalue 
); 
 976     wxVariant value 
= tmp
; 
 977     if (!cell
->Validate( value 
)) 
 980     wxDataViewListModel 
*model 
= cell
->GetOwner()->GetOwner()->GetModel(); 
 982     GtkTreePath 
*gtk_path 
= gtk_tree_path_new_from_string( path 
); 
 983     size_t model_row 
= (size_t)gtk_tree_path_get_indices (gtk_path
)[0]; 
 984     gtk_tree_path_free( gtk_path 
); 
 986     size_t model_col 
= cell
->GetOwner()->GetModelColumn(); 
 988     model
->SetValue( value
, model_col
, model_row 
); 
 989     model
->ValueChanged( model_col
, model_row 
); 
 992 IMPLEMENT_ABSTRACT_CLASS(wxDataViewToggleCell
, wxDataViewCell
) 
 994 wxDataViewToggleCell::wxDataViewToggleCell( const wxString 
&varianttype
, 
 995                         wxDataViewCellMode mode 
) : 
 996     wxDataViewCell( varianttype
, mode 
) 
 998     m_renderer 
= (void*) gtk_cell_renderer_toggle_new(); 
1000     if (m_mode 
& wxDATAVIEW_CELL_ACTIVATABLE
) 
1002         g_signal_connect_after( m_renderer
, "toggled", G_CALLBACK(wxGtkToggleRendererToggledCallback
), this ); 
1007         GValue gvalue 
= { 0, }; 
1008         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1009         g_value_set_boolean( &gvalue
, false ); 
1010         g_object_set_property( G_OBJECT(m_renderer
), "activatable", &gvalue 
); 
1011         g_value_unset( &gvalue 
); 
1013         GValue gvalue2 
= { 0, }; 
1014         g_value_init( &gvalue2
, gtk_cell_renderer_mode_get_type() ); 
1015         g_value_set_enum( &gvalue2
, GTK_CELL_RENDERER_MODE_INERT 
); 
1016         g_object_set_property( G_OBJECT(m_renderer
), "mode", &gvalue2 
); 
1017         g_value_unset( &gvalue2 
); 
1022 bool wxDataViewToggleCell::SetValue( const wxVariant 
&value 
) 
1026     GValue gvalue 
= { 0, }; 
1027     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1028     g_value_set_boolean( &gvalue
, tmp 
); 
1029     g_object_set_property( G_OBJECT(m_renderer
), "active", &gvalue 
); 
1030     g_value_unset( &gvalue 
); 
1035 bool wxDataViewToggleCell::GetValue( wxVariant 
&value 
) 
1037     GValue gvalue 
= { 0, }; 
1038     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1039     g_object_get_property( G_OBJECT(m_renderer
), "active", &gvalue 
); 
1040     bool tmp 
= g_value_get_boolean( &gvalue 
); 
1041     g_value_unset( &gvalue 
); 
1048 // --------------------------------------------------------- 
1049 // wxDataViewCustomCell 
1050 // --------------------------------------------------------- 
1052 class wxDataViewCtrlDC
: public wxWindowDC
 
1055     wxDataViewCtrlDC( wxDataViewCtrl 
*window 
) 
1057         GtkWidget 
*widget 
= window
->m_treeview
; 
1061         m_context 
= window
->GtkGetPangoDefaultContext(); 
1062         m_layout 
= pango_layout_new( m_context 
); 
1063         m_fontdesc 
= pango_font_description_copy( widget
->style
->font_desc 
); 
1065         m_cmap 
= gtk_widget_get_colormap( widget 
? widget 
: window
->m_widget 
); 
1067         // Set m_window later 
1069         // m_owner = window; 
1073 // --------------------------------------------------------- 
1074 // wxDataViewCustomCell 
1075 // --------------------------------------------------------- 
1077 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCustomCell
, wxDataViewCell
) 
1079 wxDataViewCustomCell::wxDataViewCustomCell( const wxString 
&varianttype
, 
1080                           wxDataViewCellMode mode
, bool no_init 
) : 
1081     wxDataViewCell( varianttype
, mode 
) 
1091 bool wxDataViewCustomCell::Init() 
1093     GtkWxCellRenderer 
*renderer 
= (GtkWxCellRenderer 
*) gtk_wx_cell_renderer_new(); 
1094     renderer
->cell 
= this; 
1096     m_renderer 
= (void*) renderer
; 
1098     if (m_mode 
& wxDATAVIEW_CELL_ACTIVATABLE
) 
1100         GValue gvalue 
= { 0, }; 
1101         g_value_init( &gvalue
, gtk_cell_renderer_mode_get_type() ); 
1102         g_value_set_enum( &gvalue
, GTK_CELL_RENDERER_MODE_ACTIVATABLE 
); 
1103         g_object_set_property( G_OBJECT(m_renderer
), "mode", &gvalue 
); 
1104         g_value_unset( &gvalue 
); 
1110 wxDataViewCustomCell::~wxDataViewCustomCell() 
1116 wxDC 
*wxDataViewCustomCell::GetDC() 
1120         if (GetOwner() == NULL
) 
1122         if (GetOwner()->GetOwner() == NULL
) 
1124         m_dc 
= new wxDataViewCtrlDC( GetOwner()->GetOwner() ); 
1130 // --------------------------------------------------------- 
1131 // wxDataViewProgressCell 
1132 // --------------------------------------------------------- 
1134 IMPLEMENT_ABSTRACT_CLASS(wxDataViewProgressCell
, wxDataViewCustomCell
) 
1136 wxDataViewProgressCell::wxDataViewProgressCell( const wxString 
&label
, 
1137     const wxString 
&varianttype
, wxDataViewCellMode mode 
) : 
1138     wxDataViewCustomCell( varianttype
, mode
, true ) 
1144     if (!gtk_check_version(2,6,0)) 
1146         m_renderer 
= (void*) gtk_cell_renderer_progress_new(); 
1148         GValue gvalue 
= { 0, }; 
1149         g_value_init( &gvalue
, G_TYPE_STRING 
); 
1150         g_value_set_boolean( &gvalue
, wxGTK_CONV(m_label
) ); 
1151         g_object_set_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
1152         g_value_unset( &gvalue 
); 
1157         // Use custom cell code 
1158         wxDataViewCustomCell::Init(); 
1162 wxDataViewProgressCell::~wxDataViewProgressCell() 
1166 bool wxDataViewProgressCell::SetValue( const wxVariant 
&value 
) 
1169     if (!gtk_check_version(2,6,0)) 
1171         gint tmp 
= (int) value
; 
1172         GValue gvalue 
= { 0, }; 
1173         g_value_init( &gvalue
, G_TYPE_INT 
); 
1174         g_value_set_boolean( &gvalue
, tmp 
); 
1175         g_object_set_property( G_OBJECT(m_renderer
), "value", &gvalue 
); 
1176         g_value_unset( &gvalue 
); 
1181         m_value 
= (long) value
; 
1183         if (m_value 
< 0) m_value 
= 0; 
1184         if (m_value 
> 100) m_value 
= 100; 
1190 bool wxDataViewProgressCell::Render( wxRect cell
, wxDC 
*dc
, int state 
) 
1192     double pct 
= (double)m_value 
/ 100.0; 
1194     bar
.width 
= (int)(cell
.width 
* pct
); 
1195     dc
->SetPen( *wxTRANSPARENT_PEN 
); 
1196     dc
->SetBrush( *wxBLUE_BRUSH 
); 
1197     dc
->DrawRectangle( bar 
); 
1199     dc
->SetBrush( *wxTRANSPARENT_BRUSH 
); 
1200     dc
->SetPen( *wxBLACK_PEN 
); 
1201     dc
->DrawRectangle( cell 
); 
1206 wxSize 
wxDataViewProgressCell::GetSize() 
1208     return wxSize(40,12); 
1211 // --------------------------------------------------------- 
1212 // wxDataViewDateCell 
1213 // --------------------------------------------------------- 
1215 class wxDataViewDateCellPopupTransient
: public wxPopupTransientWindow
 
1218     wxDataViewDateCellPopupTransient( wxWindow
* parent
, wxDateTime 
*value
, 
1219         wxDataViewListModel 
*model
, size_t col
, size_t row 
) : 
1220         wxPopupTransientWindow( parent
, wxBORDER_SIMPLE 
) 
1225         m_cal 
= new wxCalendarCtrl( this, -1, *value 
); 
1226         wxBoxSizer 
*sizer 
= new wxBoxSizer( wxHORIZONTAL 
); 
1227         sizer
->Add( m_cal
, 1, wxGROW 
); 
1232     virtual void OnDismiss() 
1236     void OnCalendar( wxCalendarEvent 
&event 
); 
1238     wxCalendarCtrl      
*m_cal
; 
1239     wxDataViewListModel 
*m_model
; 
1244     DECLARE_EVENT_TABLE() 
1247 BEGIN_EVENT_TABLE(wxDataViewDateCellPopupTransient
,wxPopupTransientWindow
) 
1248     EVT_CALENDAR( -1, wxDataViewDateCellPopupTransient::OnCalendar 
) 
1251 void wxDataViewDateCellPopupTransient::OnCalendar( wxCalendarEvent 
&event 
) 
1253     wxDateTime date 
= event
.GetDate(); 
1254     wxVariant value 
= date
; 
1255     m_model
->SetValue( value
, m_col
, m_row 
); 
1256     m_model
->ValueChanged( m_col
, m_row 
); 
1260 IMPLEMENT_ABSTRACT_CLASS(wxDataViewDateCell
, wxDataViewCustomCell
) 
1262 wxDataViewDateCell::wxDataViewDateCell( const wxString 
&varianttype
, 
1263                         wxDataViewCellMode mode 
) : 
1264     wxDataViewCustomCell( varianttype
, mode 
) 
1268 bool wxDataViewDateCell::SetValue( const wxVariant 
&value 
) 
1270     m_date 
= value
.GetDateTime(); 
1275 bool wxDataViewDateCell::Render( wxRect cell
, wxDC 
*dc
, int state 
) 
1277     dc
->SetFont( GetOwner()->GetOwner()->GetFont() ); 
1278     wxString tmp 
= m_date
.FormatDate(); 
1279     dc
->DrawText( tmp
, cell
.x
, cell
.y 
); 
1284 wxSize 
wxDataViewDateCell::GetSize() 
1286     wxDataViewCtrl
* view 
= GetOwner()->GetOwner(); 
1287     wxString tmp 
= m_date
.FormatDate(); 
1289     view
->GetTextExtent( tmp
, &x
, &y
, &d 
); 
1290     return wxSize(x
,y
+d
); 
1293 bool wxDataViewDateCell::Activate( wxRect cell
, wxDataViewListModel 
*model
, size_t col
, size_t row 
) 
1296     model
->GetValue( variant
, col
, row 
); 
1297     wxDateTime value 
= variant
.GetDateTime(); 
1299     wxDataViewDateCellPopupTransient 
*popup 
= new wxDataViewDateCellPopupTransient( 
1300         GetOwner()->GetOwner()->GetParent(), &value
, model
, col
, row 
); 
1301     wxPoint pos 
= wxGetMousePosition(); 
1304     popup
->Popup( popup
->m_cal 
); 
1309 // --------------------------------------------------------- 
1311 // --------------------------------------------------------- 
1314 static void wxGtkTreeCellDataFunc( GtkTreeViewColumn 
*column
, 
1315                             GtkCellRenderer 
*cell
, 
1316                             GtkTreeModel 
*model
, 
1322 static void wxGtkTreeCellDataFunc( GtkTreeViewColumn 
*column
, 
1323                             GtkCellRenderer 
*renderer
, 
1324                             GtkTreeModel 
*model
, 
1328     g_return_if_fail (GTK_IS_WX_LIST_STORE (model
)); 
1329     GtkWxListStore 
*list_store 
= (GtkWxListStore 
*) model
; 
1331     wxDataViewCell 
*cell 
= (wxDataViewCell
*) data
; 
1333     size_t model_row 
= (size_t) iter
->user_data
; 
1336     list_store
->model
->GetValue( value
, cell
->GetOwner()->GetModelColumn(), model_row 
); 
1338     if (value
.GetType() != cell
->GetVariantType()) 
1339         wxLogError( wxT("Wrong type\n") ); 
1341     cell
->SetValue( value 
); 
1344 IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumn
, wxDataViewColumnBase
) 
1346 wxDataViewColumn::wxDataViewColumn( const wxString 
&title
, wxDataViewCell 
*cell
, size_t model_column
, 
1347     int fixed_width
, wxDataViewColumnSizing sizing
, int flags 
) : 
1348     wxDataViewColumnBase( title
, cell
, model_column
, flags 
) 
1350     GtkCellRenderer 
*renderer 
= (GtkCellRenderer 
*) cell
->GetGtkHandle(); 
1352     GtkTreeViewColumn 
*column 
= gtk_tree_view_column_new(); 
1354     gtk_tree_view_column_set_title( column
, wxGTK_CONV(title
) ); 
1356     if (sizing 
== wxDATAVIEW_COL_WIDTH_FIXED
) 
1357         gtk_tree_view_column_set_sizing( column
, GTK_TREE_VIEW_COLUMN_FIXED 
); 
1358     else if (sizing 
== wxDATAVIEW_COL_WIDTH_GROW
) 
1359         gtk_tree_view_column_set_sizing( column
, GTK_TREE_VIEW_COLUMN_GROW_ONLY 
); 
1361         gtk_tree_view_column_set_sizing( column
, GTK_TREE_VIEW_COLUMN_AUTOSIZE 
); 
1363     if (fixed_width 
> 0) 
1364         gtk_tree_view_column_set_fixed_width( column
, fixed_width 
); 
1366     gtk_tree_view_column_pack_start( column
, renderer
, TRUE 
); 
1368     gtk_tree_view_column_set_cell_data_func( column
, renderer
, 
1369         wxGtkTreeCellDataFunc
, (gpointer
) cell
, NULL 
); 
1371     m_column 
= (void*) column
; 
1374 wxDataViewColumn::~wxDataViewColumn() 
1378 void wxDataViewColumn::SetTitle( const wxString 
&title 
) 
1380     wxDataViewColumnBase::SetTitle( title 
); 
1382     GtkTreeViewColumn 
*column 
= (GtkTreeViewColumn 
*)m_column
; 
1383     gtk_tree_view_column_set_title( column
, wxGTK_CONV(title
) ); 
1386 int wxDataViewColumn::GetWidth() 
1388     return gtk_tree_view_column_get_width( (GtkTreeViewColumn 
*)m_column 
); 
1391 void wxDataViewColumn::SetFixedWidth( int width 
) 
1393     gtk_tree_view_column_set_fixed_width( (GtkTreeViewColumn 
*)m_column
, width 
); 
1396 int wxDataViewColumn::GetFixedWidth() 
1398     return gtk_tree_view_column_get_fixed_width( (GtkTreeViewColumn 
*)m_column 
); 
1401 //----------------------------------------------------------------------------- 
1403 //----------------------------------------------------------------------------- 
1405 IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl
, wxDataViewCtrlBase
) 
1407 wxDataViewCtrl::~wxDataViewCtrl() 
1410         GetModel()->RemoveNotifier( m_notifier 
); 
1413 void wxDataViewCtrl::Init() 
1418 bool wxDataViewCtrl::Create(wxWindow 
*parent
, wxWindowID id
, 
1419            const wxPoint
& pos
, const wxSize
& size
, 
1420            long style
, const wxValidator
& validator 
) 
1424     m_needParent 
= true; 
1425     m_acceptsFocus 
= true; 
1427     if (!PreCreation( parent
, pos
, size 
) || 
1428         !CreateBase( parent
, id
, pos
, size
, style
, validator 
)) 
1430         wxFAIL_MSG( wxT("wxDataViewCtrl creation failed") ); 
1434     m_widget 
= gtk_scrolled_window_new (NULL
, NULL
); 
1436     GtkScrolledWindowSetBorder(m_widget
, style
); 
1438     m_treeview 
= gtk_tree_view_new(); 
1439     gtk_container_add (GTK_CONTAINER (m_widget
), m_treeview
); 
1441     if (style 
& wxDV_MULTIPLE
) 
1443         GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
1444         gtk_tree_selection_set_mode( selection
, GTK_SELECTION_MULTIPLE 
); 
1447     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_widget
), 
1448         GTK_POLICY_AUTOMATIC
, GTK_POLICY_ALWAYS
); 
1449     gtk_widget_show (m_treeview
); 
1451     m_parent
->DoAddChild( this ); 
1458 bool wxDataViewCtrl::AssociateModel( wxDataViewListModel 
*model 
) 
1460     if (!wxDataViewCtrlBase::AssociateModel( model 
)) 
1463     GtkWxListStore 
*gtk_store 
= wxgtk_list_store_new(); 
1464     gtk_store
->model 
= model
; 
1466     m_notifier 
= new wxGtkDataViewListModelNotifier( gtk_store
, model 
); 
1468     model
->AddNotifier( m_notifier 
); 
1470     gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview
), GTK_TREE_MODEL(gtk_store
) ); 
1471     g_object_unref( gtk_store 
); 
1476 bool wxDataViewCtrl::AppendColumn( wxDataViewColumn 
*col 
) 
1478     if (!wxDataViewCtrlBase::AppendColumn(col
)) 
1481     GtkTreeViewColumn 
*column 
= (GtkTreeViewColumn 
*)col
->GetGtkHandle(); 
1483     gtk_tree_view_append_column( GTK_TREE_VIEW(m_treeview
), column 
); 
1489     // !wxUSE_GENERICDATAVIEWCTRL 
1492     // wxUSE_DATAVIEWCTRL